86 lines
2.4 KiB
PHP
86 lines
2.4 KiB
PHP
<?php declare(strict_types = 1);
|
|
|
|
namespace MailPoet\Captcha;
|
|
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
|
|
use MailPoet\Config\Env;
|
|
use MailPoet\Util\Headers;
|
|
use MailPoetVendor\Gregwar\Captcha\CaptchaBuilder;
|
|
|
|
class CaptchaRenderer {
|
|
const DEFAULT_WIDTH = 220;
|
|
const DEFAULT_HEIGHT = 60;
|
|
|
|
private CaptchaPhrase $phrase;
|
|
|
|
public function __construct(
|
|
CaptchaPhrase $phrase
|
|
) {
|
|
$this->phrase = $phrase;
|
|
}
|
|
|
|
public function isSupported(): bool {
|
|
return extension_loaded('gd') && function_exists('imagettftext');
|
|
}
|
|
|
|
public function renderAudio(string $sessionId): void {
|
|
$audioPath = Env::$assetsPath . '/audio/';
|
|
$phrase = $this->getPhrase($sessionId);
|
|
|
|
$files = [];
|
|
foreach (str_split($phrase) as $character) {
|
|
$file = $audioPath . strtolower($character) . '.mp3';
|
|
if (!file_exists($file)) {
|
|
throw new \RuntimeException("File not found.");
|
|
}
|
|
$files[] = $file;
|
|
}
|
|
|
|
Headers::setNoCacheHeaders();
|
|
header('Content-Type: audio/mpeg');
|
|
foreach ($files as $file) {
|
|
readfile($file);
|
|
}
|
|
}
|
|
|
|
public function renderImage(string $sessionId, $width = null, $height = null): void {
|
|
if (!$this->isSupported()) {
|
|
return;
|
|
}
|
|
|
|
$width = (isset($width) && $width > 0) ? intval($width) : self::DEFAULT_WIDTH;
|
|
$height = (isset($height) && $height > 0) ? intval($height) : self::DEFAULT_HEIGHT;
|
|
|
|
$fontNumbers = array_merge(range(0, 3), [5]); // skip font #4
|
|
$fontNumber = $fontNumbers[mt_rand(0, count($fontNumbers) - 1)];
|
|
|
|
$reflector = new \ReflectionClass(CaptchaBuilder::class);
|
|
$captchaDirectory = dirname((string)$reflector->getFileName());
|
|
$font = $captchaDirectory . '/Font/captcha' . $fontNumber . '.ttf';
|
|
|
|
$phrase = $this->getPhrase($sessionId);
|
|
$builder = CaptchaBuilder::create($phrase)
|
|
->setBackgroundColor(255, 255, 255)
|
|
->setTextColor(1, 1, 1)
|
|
->setMaxBehindLines(0)
|
|
->build($width, $height, $font);
|
|
|
|
Headers::setNoCacheHeaders();
|
|
header('Content-Type: image/jpeg');
|
|
$builder->output();
|
|
}
|
|
|
|
public function refreshPhrase(string $sessionId): string {
|
|
return $this->phrase->createPhrase($sessionId);
|
|
}
|
|
|
|
private function getPhrase(string $sessionId): string {
|
|
$phrase = $this->phrase->getPhrase($sessionId);
|
|
if (!$phrase) {
|
|
throw new \RuntimeException("No CAPTCHA phrase was generated.");
|
|
}
|
|
return $phrase;
|
|
}
|
|
}
|