Yii2-recaptcha

Выкладываем свои наработки
Ответить
Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Yii2-recaptcha

Сообщение BrusSENS »

Привет всем. Понадобилось использование Google ReCaptcha 2.0 на одном из проектов. Существующие расширения не устроили полной непригодностью при выключенном JS. Да и городили собственные реализации работы с API Google.
Посему на коленке сделал расширение, которое:
  • Работает при выключенном JS;
  • Поддерживает несколько виджетов на странице;
  • Работает с API через библиотеку от Google.
https://github.com/brussens/yii2-recaptcha
Предложения по улучшению приветствуются.
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Yii2-recaptcha

Сообщение anton_z »

Прежде всего: Отличное расширение, спасибо.

Для ключа API лучше не делать компонент и не привязываться к конкретному названию Yii::$app->recaptcha. А запрашивать ключи в конструкторах валидатора и виджета и внедрять их через контейнер используя callback. Ну или сделать объект с конфигурацией и внедрять его, зарегистрировав в контейнере.

Класс ReCaptcha тоже надо внедрять в валидатор, по идее через конструктор, иначе вы себя лишаете возможности написать модульный тест.

Могу сделать PR.

P.S. В Yii DI конечно очень странно реализовано, но что есть то есть.
satoved
Сообщения: 14
Зарегистрирован: 2015.10.07, 17:51

Re: Yii2-recaptcha

Сообщение satoved »

Как ее обойти в acceptance тестах?
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Yii2-recaptcha

Сообщение anton_z »

satoved писал(а): 2017.02.09, 14:39 Как ее обойти в acceptance тестах?
Заменить валидатор моком через DI)
Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: Yii2-recaptcha

Сообщение BrusSENS »

anton_z писал(а): 2017.02.08, 03:03 Для ключа API лучше не делать компонент и не привязываться к конкретному названию Yii::$app->recaptcha. А запрашивать ключи в конструкторах валидатора и виджета и внедрять их через контейнер используя callback. Ну или сделать объект с конфигурацией и внедрять его, зарегистрировав в контейнере.
Спасибо, об этом думал уже. Такая реализация, через компонент, потому что надо было в резком темпе сделать что то работающее.
anton_z писал(а): 2017.02.08, 03:03 Класс ReCaptcha тоже надо внедрять в валидатор, по идее через конструктор, иначе вы себя лишаете возможности написать модульный тест.
Спасибо, думаю тоже будет не лишним.
anton_z писал(а): 2017.02.08, 03:03 Могу сделать PR.
Было бы не плохо, конечно присылайте)

А в общем спасибо за конструктивную критику) Так потихоньку расширения Yii становятся лучше)
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x
shimbo
Сообщения: 28
Зарегистрирован: 2013.06.14, 17:51

Re: Yii2-recaptcha

Сообщение shimbo »

попытался подключить и получил "банан":
PHP Warning – yii\base\ErrorException
Invalid argument supplied for foreach()
при вызове из:

Код: Выделить всё


2. in C:\WebServers\home\site.local\common\config\main.php at line 164 – yii\base\Object::__construct('config' => '', 1 => '', 2 => '')
158159160161162163164165166167168169170

            ],
        ],
    ],
    'container' => [
        'definitions' => [
            \brussens\yii2\extensions\recaptcha\Widget::class => function($container, $params, $config) {
                return new \brussens\yii2\extensions\recaptcha\Widget('***************************', \Yii::$app->language, $config);
            }
        ],
        'singletons' => [
            \ReCaptcha\ReCaptcha::class => function($container, $params, $config) {
                return new \ReCaptcha\ReCaptcha('*******************************');

Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: Yii2-recaptcha

Сообщение BrusSENS »

shimbo писал(а): 2017.06.26, 18:39 попытался подключить и получил "банан":
Было бы прекрасно, если бы описали, как появилась ошибка (фрагменты подключаемого кода и т.п.).
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x
shimbo
Сообщения: 28
Зарегистрирован: 2013.06.14, 17:51

Re: Yii2-recaptcha

Сообщение shimbo »

так все по схеме.
поставил composer-ом
шаблон advanced.
кусок из common/config/main.php:

Код: Выделить всё

    'container' => [
        'definitions' => [
            \brussens\yii2\extensions\recaptcha\Widget::class => function($container, $params, $config) {
                return new \brussens\yii2\extensions\recaptcha\Widget('********************', \Yii::$app->language, $config);
            }
        ],
        'singletons' => [
            \ReCaptcha\ReCaptcha::class => function($container, $params, $config) {
                return new \ReCaptcha\ReCaptcha('***********************');
            }
        ]
    ],
есть 2 модели:

Код: Выделить всё

class CallBack extends Model
и

Код: Выделить всё

class ContactUs extends Model
в каждой из моделей есть атрибут

Код: Выделить всё

    /**
     * for captcha
     *
     * @var string
     */
    public $verifyCode;
и соответственно прописаны одинаковые валидаторы:

Код: Выделить всё


use brussens\yii2\extensions\recaptcha\Validator as ReCaptcha;

    public function rules()
    {
        return [
            [
                [
                    'phone',
                    'message',
                ],
                'required',
            ],
            [['phone'], 'string', 'length' => 12],
            [['message'], 'string'],
            ['verifyCode', ReCaptcha::className()],
            [
                [
                    'message',
                    'phone',
                ],
                'safe',
            ],
        ];
    }
контроллер вызывает вьюху, в которой прописан вызов виджета:

Код: Выделить всё

<?php
?>

<?=\common\widgets\Feedback::widget();?>
ну в самом виджете таб и 2 формы на каждой из вкладок
внутри каждой из форм капча:

Код: Выделить всё

use brussens\yii2\extensions\recaptcha\Widget as ReCaptcha;

                                        <?=$form->field($contactUs, 'verifyCode')->widget(ReCaptcha::className(), [
                                            'options' => [
                                                'id' => 'insert-unique-widget-id-1',
                                            ],
                                        ]);?>
и такой же только для другой модели. но до него даже и не доходит. валится на первом же вызове.
shimbo
Сообщения: 28
Зарегистрирован: 2013.06.14, 17:51

Re: Yii2-recaptcha

Сообщение shimbo »

Yii 2.0.12
PHP 5.6.30
shimbo
Сообщения: 28
Зарегистрирован: 2013.06.14, 17:51

Re: Yii2-recaptcha

Сообщение shimbo »

падает тут:
\yii\BaseYii::configure

Код: Выделить всё

    /**
     * Configures an object with the initial property values.
     * @param object $object the object to be configured
     * @param array $properties the property initial values given in terms of name-value pairs.
     * @return object the object itself
     */
    public static function configure($object, $properties)
    {
        foreach ($properties as $name => $value) {
            $object->$name = $value;
        }

        return $object;
    }
потому что в $properties приходит текстовый ключ, а он пытается обратиться к нему как к массиву.
shimbo
Сообщения: 28
Зарегистрирован: 2013.06.14, 17:51

Re: Yii2-recaptcha

Сообщение shimbo »

сам себе и отвечу :)
используйте
php composer.phar require --prefer-dist brussens/yii2-recaptcha "@dev"
а не
php composer.phar require --prefer-dist brussens/yii2-recaptcha "*"
потому как после обновления до актуальной версии все заработало.
Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: Yii2-recaptcha

Сообщение BrusSENS »

shimbo писал(а): 2017.06.26, 20:09 сам себе и отвечу :)
используйте
php composer.phar require --prefer-dist brussens/yii2-recaptcha "@dev"
а не
php composer.phar require --prefer-dist brussens/yii2-recaptcha "*"
потому как после обновления до актуальной версии все заработало.
Да, именно из-за того, что релиз по другому немного работает. Немного допилю и тогда уже сделаю релиз, пока надо убедиться, что всё будет работать, как надо.
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x
akkman
Сообщения: 3
Зарегистрирован: 2017.09.18, 09:14

Re: Yii2-recaptcha

Сообщение akkman »

Всем привет, пытаюсь установить, делаю все по инструкции, но выдает ошибку:
PHP Warning – yii\base\ErrorException
Invalid argument supplied for foreach()

\yii\BaseYii::configure at 528
Yii 2.0.12
PHP 7.1.0
Yii2-recaptcha 1.0.0
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Yii2-recaptcha

Сообщение urichalex »

akkman писал(а): 2017.09.18, 09:29 Всем привет, пытаюсь установить, делаю все по инструкции, но выдает ошибку:
PHP Warning – yii\base\ErrorException
Invalid argument supplied for foreach()

\yii\BaseYii::configure at 528
Yii 2.0.12
PHP 7.1.0
Yii2-recaptcha 1.0.0
Как именно делаете? Вот прям всё в точности, как в инструкции? Если так, то ошибки не должно быть. Код свой покажите
akkman
Сообщения: 3
Зарегистрирован: 2017.09.18, 09:14

Re: Yii2-recaptcha

Сообщение akkman »

urichalex писал(а): 2017.09.18, 13:38 Код свой покажите
bootstrap:

Код: Выделить всё

<?php

namespace app\bootstrap;

use brussens\yii2\extensions\recaptcha\Widget;
use ReCaptcha\ReCaptcha;
use yii\base\BootstrapInterface;
use Yii;

class ReqBootstrap implements BootstrapInterface
{
    public function bootstrap($app)
    {
        $container = Yii::$container;

        $container->setSingleton(ReCaptcha::class, function($container)
        {
            return new ReCaptcha(RECAPTCHA_SECRET);
        });

        $container->set(Widget::class, function($container, $params, $config)
        {
            return new Widget(RECAPTCHA_KEY, Yii::$app->language, $config);
        });
    }
}
model:

Код: Выделить всё

<?php

namespace app\req\forms;

use app\req\ReqModel;
use brussens\yii2\extensions\recaptcha\Validator;

class test extends ReqModel
{
    public $verifyCode;

    public function rules()
    {
        return [
            ['verifyCode', Validator::className()]
        ];
    }
}
ReqModel:

Код: Выделить всё

use yii\base\Model;
class ReqModel extends Model
views:

Код: Выделить всё

<?= $form->field($model, 'verifyCode')
    ->widget(\brussens\yii2\extensions\recaptcha\Widget::className()) ?>
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Yii2-recaptcha

Сообщение urichalex »

И полный выхлоп ошибки
akkman
Сообщения: 3
Зарегистрирован: 2017.09.18, 09:14

Re: Yii2-recaptcha

Сообщение akkman »

urichalex писал(а): 2017.09.18, 17:19 И полный выхлоп ошибки
Проблема решилась, после того как взял файл Widget.php с ветки `master`

в релизе в файле Widget.php отсутствовал конструктор

Код: Выделить всё

__construct($siteKey, $language, $config = [])
update: валидация тоже работала некорректно, заработала после того, как заменил файл Validator.php из ветки `master`
Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: Yii2-recaptcha

Сообщение BrusSENS »

akkman писал(а): 2017.09.18, 19:04 Проблема решилась, после того как взял файл Widget.php с ветки `master`

в релизе в файле Widget.php отсутствовал конструктор

Код: Выделить всё

__construct($siteKey, $language, $config = [])
update: валидация тоже работала некорректно, заработала после того, как заменил файл Validator.php из ветки `master`
Пока что не хватает времени допилить, что бы релизнуть. Постараюсь как можно быстрее запилить релиз.
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x
Ответить