JezK
Edit File: CaptchaValidatorAbstract.php
<?php namespace GeminiLabs\SiteReviews\Modules\Validator; use GeminiLabs\SiteReviews\Api; use GeminiLabs\SiteReviews\Helper; use GeminiLabs\SiteReviews\Helpers\Arr; use GeminiLabs\SiteReviews\Helpers\Str; use GeminiLabs\SiteReviews\Response; abstract class CaptchaValidatorAbstract extends ValidatorAbstract { public const API_URL = ''; public const CAPTCHA_DISABLED = 0; public const CAPTCHA_EMPTY = 1; public const CAPTCHA_FAILED = 2; public const CAPTCHA_INVALID = 3; public const CAPTCHA_VALID = 4; protected $status; abstract public function config(): array; public function isEnabled(): bool { return false; } public function isValid(): bool { if (in_array($this->status, [static::CAPTCHA_DISABLED, static::CAPTCHA_VALID])) { return true; } return false; } public function performValidation(): void { $this->status = $this->verifyStatus(); if ($this->isValid()) { return; } $error = Helper::ifTrue($this->status === static::CAPTCHA_FAILED, __('The CAPTCHA failed to load, please refresh the page and try again.', 'site-reviews'), __('The CAPTCHA verification failed, please try again.', 'site-reviews') ); $this->fail($error); } protected function errors(array $errors): array { $codes = $this->errorCodes(); $errors = array_fill_keys($errors, ''); return array_merge( array_intersect_key($codes, $errors), // known errors array_diff_key($errors, $codes) // unknown errors ); } protected function errorCodes(): array { return []; } protected function getLocale(): string { $locale = ''; if (function_exists('locale_parse')) { $values = locale_parse(get_locale()); if (!empty($values['language'])) { $locale = $values['language']; } } return glsr()->filterString('captcha/language', $locale); } protected function isTokenValid(array $responseBody): bool { return $responseBody['success']; } protected function requestArgs(array $body): array { return [ 'body' => $body, 'force' => true, ]; } protected function requestBody(): array { return []; } protected function responseBody(Response $response): array { $body = $response->body(); $errors = Arr::consolidate($body['error-codes'] ?? $body['errors'] ?? $body['error'] ?? []); return [ 'action' => $body['action'] ?? '', 'errors' => $this->errors($errors), 'score' => $body['score'] ?? 0, 'success' => wp_validate_boolean($body['success'] ?? false), ]; } protected function siteKey(): string { return ''; } protected function siteSecret(): string { return ''; } protected function token(): string { return $this->request['_captcha'] ?? ''; } protected function verifyStatus(): int { if (!$this->isEnabled()) { return static::CAPTCHA_DISABLED; } return $this->verifyToken(); } protected function verifyToken(): int { if (empty($this->token())) { return static::CAPTCHA_EMPTY; // fail early } $body = $this->requestBody(); $response = glsr(Api::class, ['url' => static::API_URL])->post('', $this->requestArgs($body)); if ($response->failed()) { return static::CAPTCHA_FAILED; } $responseBody = $this->responseBody($response); if ($this->isTokenValid($responseBody)) { return static::CAPTCHA_VALID; } if (!empty($responseBody['errors'])) { $body['secret'] = Str::mask($this->siteSecret(), 4, 4, 20); $body['sitekey'] = Str::mask($this->siteKey(), 4, 4, 20); glsr_log()->error($responseBody)->debug($body); } if (empty($this->siteSecret()) || empty($this->siteKey())) { return static::CAPTCHA_FAILED; } return static::CAPTCHA_INVALID; } }