Completed
Push — master ( d20546...0b3f53 )
by ARCANEDEV
17s queued 15s
created

NoCaptchaV2::hasCallbackName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 2
1
<?php namespace Arcanedev\NoCaptcha;
2
3
use Arcanedev\NoCaptcha\Utilities\Attributes;
4
use Arcanedev\NoCaptcha\Utilities\ResponseV2;
5
use Illuminate\Support\Arr;
6
7
/**
8
 * Class     NoCaptchaV2
9
 *
10
 * @package  Arcanedev\NoCaptcha
11
 * @author   ARCANEDEV <[email protected]>
12
 */
13
class NoCaptchaV2 extends AbstractNoCaptcha
14
{
15
    /* -----------------------------------------------------------------
16
     |  Properties
17
     | -----------------------------------------------------------------
18
     */
19
20
    /**
21
     * Decides if we've already loaded the script file or not.
22
     *
23
     * @param bool
24
     */
25
    protected $scriptLoaded = false;
26
27
    /**
28
     * noCaptcha Attributes
29
     *
30
     * @var \Arcanedev\NoCaptcha\Utilities\Attributes
31
     */
32
    protected $attributes;
33
34
    /* -----------------------------------------------------------------
35
     |  Constructor
36
     | -----------------------------------------------------------------
37
     */
38
39
    /**
40
     * NoCaptcha constructor.
41
     *
42
     * @param  string       $secret
43
     * @param  string       $siteKey
44
     * @param  string|null  $lang
45
     * @param  array        $attributes
46
     */
47 128
    public function __construct($secret, $siteKey, $lang = null, array $attributes = [])
48
    {
49 128
        parent::__construct($secret, $siteKey, $lang);
50
51 128
        $this->setAttributes(new Attributes($attributes));
52 128
    }
53
54
    /* -----------------------------------------------------------------
55
     |  Getters & Setters
56
     | -----------------------------------------------------------------
57
     */
58
59
    /**
60
     * Get script source link.
61
     *
62
     * @param  string|null  $callbackName
63
     *
64
     * @return string
65
     */
66 20
    private function getScriptSrc($callbackName = null)
67
    {
68 20
        $queries = [];
69
70 20
        if ($this->hasLang())
71 8
            Arr::set($queries, 'hl', $this->lang);
72
73 20
        if ($this->hasCallbackName($callbackName)) {
74 4
            Arr::set($queries, 'onload', $callbackName);
75 4
            Arr::set($queries, 'render', 'explicit');
76
        }
77
78 20
        return static::CLIENT_URL . (count($queries) ? '?' . http_build_query($queries) : '');
79
    }
80
81
    /**
82
     * Set noCaptcha Attributes.
83
     *
84
     * @param  \Arcanedev\NoCaptcha\Utilities\Attributes  $attributes
85
     *
86
     * @return self
87
     */
88 128
    public function setAttributes(Attributes $attributes)
89
    {
90 128
        $this->attributes = $attributes;
91
92 128
        return $this;
93
    }
94
95
    /* -----------------------------------------------------------------
96
     |  Main Methods
97
     | -----------------------------------------------------------------
98
     */
99
100
    /**
101
     * Display Captcha.
102
     *
103
     * @param  string|null  $name
104
     * @param  array        $attributes
105
     *
106
     * @return \Illuminate\Support\HtmlString
107
     */
108 76
    public function display($name = null, array $attributes = [])
109
    {
110 76
        $attributes = $this->attributes->build($this->siteKey, array_merge(
111 76
            $this->attributes->prepareNameAttribute($name),
112 32
            $attributes
113
        ));
114
115 64
        return $this->toHtmlString("<div {$attributes}></div>");
116
    }
117
118
    /**
119
     * Display image Captcha.
120
     *
121
     * @param  string|null  $name
122
     * @param  array        $attributes
123
     *
124
     * @return \Illuminate\Support\HtmlString
125
     */
126 12
    public function image($name = null, array $attributes = [])
127
    {
128 12
        return $this->display(
129 12
            $name, array_merge($attributes, $this->attributes->getImageAttribute())
130
        );
131
    }
132
133
    /**
134
     * Display audio Captcha.
135
     *
136
     * @param  string|null  $name
137
     * @param  array        $attributes
138
     *
139
     * @return \Illuminate\Support\HtmlString
140
     */
141 12
    public function audio($name = null, array $attributes = [])
142
    {
143 12
        return $this->display(
144 12
            $name, array_merge($attributes, $this->attributes->getAudioAttribute())
145
        );
146
    }
147
    /**
148
     * Display an invisible Captcha (bind the challenge to a button).
149
     *
150
     * @param  string  $value
151
     * @param  array   $attributes
152
     *
153
     * @return \Illuminate\Support\HtmlString
154
     */
155 4
    public function button($value, array $attributes = [])
156
    {
157 4
        $attributes = $this->attributes->build($this->siteKey, array_merge([
158 4
            'data-callback' => 'onSubmit',
159 2
        ], $attributes));
160
161 4
        return $this->toHtmlString(
162 4
            "<button {$attributes}>{$value}</button>"
163
        );
164
    }
165
166
    /**
167
     * Get script tag.
168
     *
169
     * @param  string|null  $callbackName
170
     *
171
     * @return \Illuminate\Support\HtmlString
172
     */
173 20
    public function script($callbackName = null)
174
    {
175 20
        $script = '';
176
177 20
        if ( ! $this->scriptLoaded) {
178 20
            $script = '<script src="'.$this->getScriptSrc($callbackName).'" async defer></script>';
179 20
            $this->scriptLoaded = true;
180
        }
181
182 20
        return $this->toHtmlString($script);
183
    }
184
185
    /**
186
     * Get the NoCaptcha API Script.
187
     *
188
     * @return \Illuminate\Support\HtmlString
189
     */
190 4
    public function getApiScript()
191
    {
192 4
        return $this->toHtmlString(
193 3
            "<script>
194
                window.noCaptcha = {
195
                    captchas: [],
196
                    reset: function(name) {
197
                        var captcha = window.noCaptcha.get(name);
198
        
199
                        if (captcha)
200
                            window.noCaptcha.resetById(captcha.id);
201
                    },
202
                    resetById: function(id) {
203
                        grecaptcha.reset(id);
204
                    },
205
                    get: function(name) {
206
                        return window.noCaptcha.find(function (captcha) {
207
                            return captcha.name === name;
208
                        });
209
                    },
210
                    getById: function(id) {
211
                        return window.noCaptcha.find(function (captcha) {
212
                            return captcha.id === id;
213
                        });
214
                    },
215
                    find: function(callback) {
216
                        return window.noCaptcha.captchas.find(callback);
217
                    },
218
                    render: function(name, sitekey) {
219
                        var captcha = {
220
                            id: grecaptcha.render(name, {'sitekey' : sitekey}),
221
                            name: name
222
                        };
223
                        
224
                        window.noCaptcha.captchas.push(captcha);
225
                        
226
                        return captcha;
227
                    }
228
                }
229 1
            </script>"
230
        );
231
    }
232
233
    /**
234
     * Get script tag with a callback function.
235
     *
236
     * @param  array   $captchas
237
     * @param  string  $callbackName
238
     *
239
     * @return \Illuminate\Support\HtmlString
240
     */
241 4
    public function scriptWithCallback(array $captchas, $callbackName = 'captchaRenderCallback')
242
    {
243 4
        $script = $this->script($callbackName)->toHtml();
244
245 4
        if ( ! empty($script) && ! empty($captchas)) {
246 4
            $script = implode(PHP_EOL, [implode(PHP_EOL, [
247 4
                $this->getApiScript()->toHtml(),
248 4
                '<script>',
249 4
                    "var $callbackName = function() {",
250 4
                        $this->renderCaptchas($captchas),
251 4
                    '};',
252 4
                '</script>'
253 4
            ]), $script]);
254
        }
255
256 4
        return $this->toHtmlString($script);
257
    }
258
259
    /**
260
     * Rendering captchas with callback function.
261
     *
262
     * @param  array  $captchas
263
     *
264
     * @return string
265
     */
266 4
    private function renderCaptchas(array $captchas)
267
    {
268
        return implode(PHP_EOL, array_map(function($captcha) {
269 4
            return "if (document.getElementById('{$captcha}')) { window.noCaptcha.render('{$captcha}', '{$this->siteKey}'); }";
270 4
        }, $captchas));
271
    }
272
273
    /* -----------------------------------------------------------------
274
     |  Check Methods
275
     | -----------------------------------------------------------------
276
     */
277
278
    /**
279
     * Check if callback is not empty.
280
     *
281
     * @param  string|null  $callbackName
282
     *
283
     * @return bool
284
     */
285 20
    private function hasCallbackName($callbackName)
286
    {
287 20
        return ! (is_null($callbackName) || trim($callbackName) === '');
288
    }
289
290
    /* -----------------------------------------------------------------
291
     |  Other Methods
292
     | -----------------------------------------------------------------
293
     */
294
295
    /**
296
     * Parse the response.
297
     *
298
     * @param  string  $json
299
     *
300
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
301
     */
302 12
    protected function parseResponse($json)
303
    {
304 12
        return ResponseV2::fromJson($json);
305
    }
306
}
307