ReCaptchaWidget   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 5
dl 0
loc 149
ccs 0
cts 77
cp 0
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 10 2
A run() 0 12 2
A getCaptchaOptions() 0 19 1
A registerClientScript() 0 30 3
A getLanguageCode() 0 23 3
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User\Widget;
13
14
use Yii;
15
use yii\base\InvalidConfigException;
16
use yii\helpers\Html;
17
use yii\web\View;
18
use yii\widgets\InputWidget;
19
20
class ReCaptchaWidget extends InputWidget
21
{
22
    /**
23
     * @var string the color theme of the widget. Values can be 'dark' or 'light'. Optional.
24
     */
25
    public $theme;
26
    /**
27
     * @var string the type of captcha. Values can be 'audio' or 'image'. Optional.
28
     */
29
    public $type;
30
    /**
31
     * @var string the size of the widget. Values can be 'compact' or 'normal'. Optional.
32
     */
33
    public $size;
34
    /**
35
     * @var string the tabindex of the widget and challenge. Optional.
36
     */
37
    public $tabIndex;
38
    /**
39
     * @var string the name of the callbaqck function to be executed when the user submits a
40
     *             successful CAPTCHA response. The user's response, *g-recaptcha-response*, will be the input
41
     *             for the callback function. Optional.
42
     */
43
    public $callback;
44
    /**
45
     * @var string the name of the callback function to be executed when the recaptcha response
46
     *             expires and the user needs to solve a new CAPTCHA.
47
     */
48
    public $expiredCallback;
49
50
    /**
51
     * @inheritdoc
52
     *
53
     * @throws InvalidConfigException
54
     */
55
    public function init()
56
    {
57
        if (!Yii::$app->get('recaptcha')) {
58
            throw new InvalidConfigException(Yii::t('usuario', 'The "recaptcha" component must be configured.'));
59
        }
60
61
        parent::init();
62
63
        $this->registerClientScript();
64
    }
65
66
    /**
67
     * @inheritdoc
68
     *
69
     * @throws InvalidConfigException
70
     */
71
    public function run()
72
    {
73
        $html = [];
74
75
        $html[] = $this->hasModel()
76
            ? Html::activeHiddenInput($this->model, $this->attribute, $this->options)
77
            : Html::hiddenInput($this->name, null, $this->options);
78
79
        $html[] = Html::tag('div', '', $this->getCaptchaOptions());
80
81
        return implode("\n", $html);
82
    }
83
84
    /**
85
     * @throws InvalidConfigException
86
     * @return array                  the google recaptcha options.
87
     */
88
    protected function getCaptchaOptions()
89
    {
90
        $data = [
91
            'sitekey' => Yii::$app->get('recaptcha')->key,
92
            'callback' => $this->callback,
93
            'expired-callback' => $this->expiredCallback,
94
            'theme' => $this->theme,
95
            'type' => $this->type,
96
            'size' => $this->size,
97
            'tabindex' => $this->tabIndex
98
        ];
99
100
        $options = [
101
            'class' => 'g-recaptcha',
102
            'data' => array_filter($data)
103
        ];
104
105
        return $options;
106
    }
107
108
    /**
109
     * Registers the required libraries and scripts for the widget to work.
110
     */
111
    protected function registerClientScript()
112
    {
113
        $view = $this->getView();
114
115
        $view->registerJsFile(
116
            '//www.google.com/recaptcha/api.js?hl=' . $this->getLanguageCode(),
117
            [
118
                'position' => View::POS_HEAD,
119
                'async' => true,
120
                'defer' => true
121
            ]
122
        );
123
124
        $js = [];
125
        $id = $this->options['id'];
126
127
        $js[] = empty($this->callback)
128
            ? "var reCaptchaCallback = function(r){jQuery('#{$id}').val(r);};"
129
            : "var reCaptchaCallback = function(r){jQuery('#{$id}').val(r); {$this->callback}(r);};";
130
131
        $this->callback = 'reCaptchaCallback';
132
133
        $js[] = empty($this->expiredCallback)
134
            ? "var reCaptchaExpiredCallback = function(){jQuery('#{$id}').val('');};"
135
            : "var reCaptchaExpiredCallback = function(){jQuery('#{$id}').val(''); {$this->expiredCallback}();};";
136
137
        $this->expiredCallback = 'reCaptchaExpiredCallback';
138
139
        $view->registerJs(implode("\n", $js), View::POS_BEGIN);
140
    }
141
142
    /**
143
     * @return bool|string the language code config option for google recatpcha library url.
144
     */
145
    protected function getLanguageCode()
146
    {
147
        $language = Yii::$app->language;
148
149
        if (strpos($language, '-') === false) {
150
            return $language;
151
        }
152
153
        $except = [
154
            'zh-HK',
155
            'zh-CN',
156
            'zh-TW',
157
            'en-GB',
158
            'de-AT',
159
            'de-CH',
160
            'pt-BR',
161
            'pt-PT'
162
        ];
163
164
        return in_array($language, $except, false)
165
            ? $language
166
            : substr($language, 0, strpos($language, '-'));
167
    }
168
}
169