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

AbstractNoCaptcha::hasLang()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php namespace Arcanedev\NoCaptcha;
2
3
use Arcanedev\NoCaptcha\Utilities\Request;
4
use Illuminate\Support\HtmlString;
5
use Psr\Http\Message\ServerRequestInterface;
6
7
/**
8
 * Class     AbstractNoCaptcha
9
 *
10
 * @package  Arcanedev\NoCaptcha
11
 * @author   ARCANEDEV <[email protected]>
12
 */
13
abstract class AbstractNoCaptcha implements Contracts\NoCaptcha
14
{
15
    /* -----------------------------------------------------------------
16
     |  Constants
17
     | -----------------------------------------------------------------
18
     */
19
20
    const CLIENT_URL   = 'https://www.google.com/recaptcha/api.js';
21
    const VERIFY_URL   = 'https://www.google.com/recaptcha/api/siteverify';
22
    const CAPTCHA_NAME = 'g-recaptcha-response';
23
24
    /* -----------------------------------------------------------------
25
     |  Properties
26
     | -----------------------------------------------------------------
27
     */
28
29
    /**
30
     * The shared key between your site and ReCAPTCHA
31
     *
32
     * @var string
33
     */
34
    protected $secret;
35
36
    /**
37
     * Your site key
38
     *
39
     * @var string
40
     */
41
    protected $siteKey;
42
43
    /**
44
     * Forces the widget to render in a specific language.
45
     * Auto-detects the user's language if unspecified.
46
     *
47
     * @var string
48
     */
49
    protected $lang;
50
51
    /**
52
     * HTTP Request Client
53
     *
54
     * @var \Arcanedev\NoCaptcha\Contracts\Utilities\Request
55
     */
56
    protected $request;
57
58
    /**
59
     * ReCaptcha's response.
60
     *
61
     * @var \Arcanedev\NoCaptcha\Utilities\ResponseV3|null
62
     */
63
    protected $response;
64
65
    /* -----------------------------------------------------------------
66
     |  Constructor
67
     | -----------------------------------------------------------------
68
     */
69
70
    /**
71
     * NoCaptcha constructor.
72
     *
73
     * @param  string       $secret
74
     * @param  string       $siteKey
75
     * @param  string|null  $lang
76
     */
77 216
    public function __construct($secret, $siteKey, $lang = null)
78
    {
79 216
        $this->setSecret($secret);
80 216
        $this->setSiteKey($siteKey);
81 216
        $this->setLang($lang);
82
83 216
        $this->setRequestClient(new Request);
84 216
    }
85
86
    /* -----------------------------------------------------------------
87
     |  Getters & Setters
88
     | -----------------------------------------------------------------
89
     */
90
91
    /**
92
     * Set the secret key.
93
     *
94
     * @param  string  $secret
95
     *
96
     * @return $this
97
     */
98 216
    protected function setSecret($secret)
99
    {
100 216
        self::checkKey('secret key', $secret);
101
102 216
        $this->secret = $secret;
103
104 216
        return $this;
105
    }
106
107
    /**
108
     * Get the site key.
109
     *
110
     * @return string
111
     */
112 24
    public function getSiteKey()
113
    {
114 24
        return $this->siteKey;
115
    }
116
117
    /**
118
     * Set Site key.
119
     *
120
     * @param  string  $siteKey
121
     *
122
     * @return $this
123
     */
124 216
    protected function setSiteKey($siteKey)
125
    {
126 216
        self::checkKey('site key', $siteKey);
127
128 216
        $this->siteKey = $siteKey;
129
130 216
        return $this;
131
    }
132
133
    /**
134
     * Set language code.
135
     *
136
     * @param  string  $lang
137
     *
138
     * @return $this
139
     */
140 216
    public function setLang($lang)
141
    {
142 216
        $this->lang = $lang;
143
144 216
        return $this;
145
    }
146
147
    /**
148
     * Set HTTP Request Client.
149
     *
150
     * @param  \Arcanedev\NoCaptcha\Contracts\Utilities\Request  $request
151
     *
152
     * @return $this
153
     */
154 216
    public function setRequestClient(Contracts\Utilities\Request $request)
155
    {
156 216
        $this->request = $request;
157
158 216
        return $this;
159
    }
160
161
    /**
162
     * Get the last response.
163
     *
164
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|null
165
     */
166 4
    public function getLastResponse()
167
    {
168 4
        return $this->response;
169
    }
170
171
    /* -----------------------------------------------------------------
172
     |  Main Methods
173
     | -----------------------------------------------------------------
174
     */
175
176
    /**
177
     * Verify Response.
178
     *
179
     * @param  string  $response
180
     * @param  string  $clientIp
181
     *
182
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
183
     */
184 32
    public function verify($response, $clientIp = null)
185
    {
186 32
        return $this->response = $this->sendVerifyRequest([
187 32
            'secret'   => $this->secret,
188 32
            'response' => $response,
189 32
            'remoteip' => $clientIp
190
        ]);
191
    }
192
193
    /**
194
     * Calls the reCAPTCHA siteverify API to verify whether the user passes CAPTCHA
195
     * test using a PSR-7 ServerRequest object.
196
     *
197
     * @param  \Psr\Http\Message\ServerRequestInterface  $request
198
     *
199
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse
200
     */
201 8
    public function verifyRequest(ServerRequestInterface $request)
202
    {
203 8
        $body   = $request->getParsedBody();
204 8
        $server = $request->getServerParams();
205
206 8
        return $this->verify(
207 8
            $body[self::CAPTCHA_NAME] ?? '',
208 8
            $server['REMOTE_ADDR'] ?? null
209
        );
210
    }
211
212
    /**
213
     * Send verify request to API and get response.
214
     *
215
     * @param  array  $query
216
     *
217
     * @return \Arcanedev\NoCaptcha\Utilities\ResponseV3
218
     */
219 32
    protected function sendVerifyRequest(array $query = [])
220
    {
221 32
        $query = array_filter($query);
222 32
        $json  = $this->request->send(
223 32
            static::VERIFY_URL.'?'.http_build_query($query)
224
        );
225
226 32
        return $this->parseResponse($json);
227
    }
228
229
    /**
230
     * Parse the response.
231
     *
232
     * @param  string  $json
233
     *
234
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
235
     */
236
    abstract protected function parseResponse($json);
237
238
    /* -----------------------------------------------------------------
239
     |  Check Methods
240
     | -----------------------------------------------------------------
241
     */
242
243
    /**
244
     * Check if has lang.
245
     *
246
     * @return bool
247
     */
248 40
    protected function hasLang()
249
    {
250 40
        return ! empty($this->lang);
251
    }
252
253
    /**
254
     * Check key.
255
     *
256
     * @param  string  $name
257
     * @param  string  $value
258
     */
259 216
    private static function checkKey($name, &$value)
260
    {
261 216
        self::checkIsString($name, $value);
262
263 216
        $value = trim($value);
264
265 216
        self::checkIsNotEmpty($name, $value);
266 216
    }
267
268
    /**
269
     * Check if the value is a string value.
270
     *
271
     * @param  string  $name
272
     * @param  string  $value
273
     *
274
     * @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
275
     */
276 216
    private static function checkIsString($name, $value)
277
    {
278 216
        if ( ! is_string($value)) {
279 16
            throw new Exceptions\ApiException(
280 16
                "The {$name} must be a string value, ".gettype($value).' given.'
281
            );
282
        }
283 216
    }
284
285
    /**
286
     * Check if the value is not empty.
287
     *
288
     * @param string  $name
289
     * @param string  $value
290
     *
291
     * @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
292
     */
293 216
    private static function checkIsNotEmpty($name, $value)
294
    {
295 216
        if (empty($value)) {
296 16
            throw new Exceptions\ApiException("The {$name} must not be empty");
297
        }
298 216
    }
299
300
    /* -----------------------------------------------------------------
301
     |  Other Methods
302
     | -----------------------------------------------------------------
303
     */
304
305
    /**
306
     * Transform the string to an Html serializable object
307
     *
308
     * @param  string  $html
309
     *
310
     * @return \Illuminate\Support\HtmlString
311
     */
312 124
    protected function toHtmlString($html)
313
    {
314 124
        return new HtmlString($html);
315
    }
316
}
317