![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/laminas/laminas-recaptcha/src/ |
<?php declare(strict_types=1); namespace Laminas\ReCaptcha; use Exception as PhpException; use Laminas\Http\Client as HttpClient; use Laminas\Http\Request as HttpRequest; use Laminas\Stdlib\ArrayUtils; use Stringable; use Traversable; use function get_debug_type; use function is_array; use function sprintf; use function trigger_error; use const E_USER_WARNING; /** * Render and verify ReCaptchas * * @final This class should not be extended and will be marked final in version 4.0 */ class ReCaptcha implements Stringable { /** * URI to the API * * @var string */ public const API_SERVER = 'https://www.google.com/recaptcha/api'; /** * URI to the verify server * * @var string */ public const VERIFY_SERVER = 'https://www.google.com/recaptcha/api/siteverify'; /** * Site key used when displaying the captcha * * @var string */ protected $siteKey; /** * Secret key used when verifying user input * * @var string */ protected $secretKey; /** * Ip address used when verifying user input * * @var string */ protected $ip; /** * Parameters for the object * * @var array<string, mixed> */ protected $params = [ 'noscript' => false, /* Includes the <noscript> tag */ ]; /** * Options for tailoring reCaptcha * * See the different options on https://developers.google.com/recaptcha/docs/display#config * * @var array<string, mixed> */ protected $options = [ 'theme' => 'light', 'type' => 'image', 'size' => 'normal', 'tabindex' => 0, 'callback' => null, 'expired-callback' => null, 'hl' => null, // Auto-detect language ]; /** @var HttpClient */ protected $httpClient; /** * @param string $siteKey * @param string $secretKey * @param iterable<string, mixed> $params * @param iterable<string, mixed> $options * @param string $ip */ public function __construct( $siteKey = null, $secretKey = null, $params = null, $options = null, $ip = null, ?HttpClient $httpClient = null ) { if ($siteKey !== null) { $this->setSiteKey($siteKey); } if ($secretKey !== null) { $this->setSecretKey($secretKey); } if ($ip !== null) { $this->setIp($ip); } elseif (isset($_SERVER['REMOTE_ADDR'])) { $this->setIp($_SERVER['REMOTE_ADDR']); } if ($params !== null) { $this->setParams($params); } if ($options !== null) { $this->setOptions($options); } $this->setHttpClient($httpClient ?: new HttpClient()); } /** @return $this */ public function setHttpClient(HttpClient $httpClient) { $this->httpClient = $httpClient; return $this; } /** @return HttpClient */ public function getHttpClient() { return $this->httpClient; } /** * Serialize as string * * When the instance is used as a string it will display the recaptcha. * Since we can't throw exceptions within this method we will trigger * a user warning instead. */ public function __toString(): string { try { $return = $this->getHtml(); } catch (PhpException $phpException) { $return = ''; trigger_error($phpException->getMessage(), E_USER_WARNING); } return $return; } /** * Set the ip property * * @param string $ip * @return self */ public function setIp($ip) { $this->ip = $ip; return $this; } /** * Get the ip property * * @return string */ public function getIp() { return $this->ip; } /** * Set a single parameter * * @param string $key * @param mixed $value * @return self */ public function setParam($key, $value) { $this->params[$key] = $value; return $this; } /** * Set parameters * * @param iterable<string, mixed> $params * @return self * @throws Exception */ public function setParams($params) { if ($params instanceof Traversable) { $params = ArrayUtils::iteratorToArray($params); } if (! is_array($params)) { throw new Exception(sprintf( '%s expects an array or Traversable set of params; received "%s"', __METHOD__, get_debug_type($params) )); } foreach ($params as $k => $v) { $this->setParam($k, $v); } return $this; } /** * Get the parameter array * * @return array<string, mixed> */ public function getParams() { return $this->params; } /** * Get a single parameter * * @param string $key * @return mixed */ public function getParam($key) { if (! isset($this->params[$key])) { return null; } return $this->params[$key]; } /** * Set a single option * * @param string $key * @param mixed $value * @return self */ public function setOption($key, $value) { $this->options[$key] = $value; return $this; } /** * Set options * * @param iterable<string, mixed> $options * @return self * @throws Exception */ public function setOptions($options) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (is_array($options)) { foreach ($options as $k => $v) { $this->setOption($k, $v); } } else { throw new Exception('Expected array or Traversable object'); } return $this; } /** * Get the options array * * @return array<string, mixed> */ public function getOptions() { return $this->options; } /** * Get a single option * * @param string $key * @return mixed */ public function getOption($key) { if (! isset($this->options[$key])) { return null; } return $this->options[$key]; } /** * Get the site key * * @return string */ public function getSiteKey() { return $this->siteKey; } /** * Set the site key * * @param string $siteKey * @return self */ public function setSiteKey($siteKey) { $this->siteKey = $siteKey; return $this; } /** * Get the secret key * * @return string */ public function getSecretKey() { return $this->secretKey; } /** * Set the secret key * * @param string $secretKey * @return self */ public function setSecretKey($secretKey) { $this->secretKey = $secretKey; return $this; } /** * Get the HTML code for the captcha * * This method uses the public key to fetch a recaptcha form. * * @return string * @throws Exception */ public function getHtml() { if ($this->siteKey === null) { throw new Exception('Missing site key'); } $host = self::API_SERVER; // Should we use an onload callback? if (! empty($this->options['onload'])) { return sprintf( '<script type="text/javascript" src="%s.js?onload=%s&render=explicit" async defer></script>', $host, $this->options['onload'] ); } $langOption = ''; if (! empty($this->options['hl'])) { $langOption = sprintf('?hl=%s', $this->options['hl']); } $data = sprintf('data-sitekey="%s"', $this->siteKey); foreach ( [ 'theme', 'type', 'size', 'tabindex', 'callback', 'expired-callback', ] as $option ) { if (! empty($this->options[$option])) { $data .= sprintf(' data-%s="%s"', $option, $this->options[$option]); } } $return = <<<HTML <script type="text/javascript" src="{$host}.js{$langOption}" async defer></script> <div class="g-recaptcha" {$data}></div> HTML; if ($this->params['noscript']) { $return .= <<<HTML <noscript> <div style="width: 302px; height: 422px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="{$host}/fallback?k={$this->siteKey}" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"> </iframe> </div> <div style="width: 300px; height: 60px; border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid #c1c1c1; margin: 10px 25px; padding: 0px; resize: none;" > </textarea> </div> </div> </div> </noscript> HTML; } return $return; } /** * Gets a solution to the verify server * * @param string $responseField * @return \Laminas\Http\Response * @throws Exception */ protected function post($responseField) { if ($this->secretKey === null) { throw new Exception('Missing secret key'); } if ($this->ip === null) { throw new Exception('Missing ip address'); } /* Fetch an instance of the http client */ $httpClient = $this->getHttpClient(); $params = [ 'secret' => $this->secretKey, 'remoteip' => $this->ip, 'response' => $responseField, ]; $request = new HttpRequest(); $request->setUri(self::VERIFY_SERVER); $request->getPost()->fromArray($params); $request->setMethod(HttpRequest::METHOD_POST); $httpClient->setEncType($httpClient::ENC_URLENCODED); return $httpClient->send($request); } /** * Verify the user input * * This method calls up the post method and returns a * \Laminas\ReCaptcha\Response object. * * @param string $responseField * @return Response */ public function verify($responseField) { $response = $this->post($responseField); return new Response(null, null, $response); } }