session = Grav::instance()['session']; } public function getCaptchaCode($length = null): string { $config = Grav::instance()['config']->get('plugins.form.basic_captcha'); $type = $config['type'] ?? 'characters'; if ($type == 'math') { $min = $config['math']['min'] ?? 1; $max = $config['math']['max'] ?? 12; $operators = $config['math']['operators'] ?? ['+','-','*']; $first_num = random_int($min, $max); $second_num = random_int($min, $max); $operator = $operators[array_rand($operators)]; // calculator if ($operator === '-') { if ($first_num < $second_num) { $result = "$second_num - $first_num"; $captcha_code = $second_num - $first_num; } else { $result = "$first_num-$second_num"; $captcha_code = $first_num - $second_num; } } elseif ($operator === '*') { $result = "{$first_num} x {$second_num}"; $captcha_code = $first_num * $second_num; } elseif ($operator === '/') { $result = "$first_num / second_num"; $captcha_code = $first_num / $second_num; } elseif ($operator === '+') { $result = "$first_num + $second_num"; $captcha_code = $first_num + $second_num; } } else { if ($length === null) { $length = $config['chars']['length'] ?? 6; } $random_alpha = md5(random_bytes(64)); $captcha_code = substr($random_alpha, 0, $length); $result = $captcha_code; } $this->setSession($this->key, $captcha_code); return $result; } public function setSession($key, $value): void { $this->session->$key = $value; } public function getSession($key = null): ?string { if ($key === null) { $key = $this->key; } return $this->session->$key ?? null; } public function createCaptchaImage($captcha_code) { $config = Grav::instance()['config']->get('plugins.form.basic_captcha'); $font = $config['chars']['font'] ?? 'zxx-xed.ttf'; $target_layer = imagecreatetruecolor($config['chars']['box_width'], $config['chars']['box_height']); $bg = $this->hexToRgb($config['chars']['bg'] ?? '#ffffff'); $text = $this->hexToRgb($config['chars']['text'] ?? '#000000'); $captcha_background = imagecolorallocate($target_layer, $bg[0], $bg[1], $bg[2]); $captcha_text_color = imagecolorallocate($target_layer, $text[0], $text[1], $text[2]); $font_path = __DIR__ . '/../fonts/' . $font; imagefill($target_layer, 0, 0, $captcha_background); imagefttext($target_layer, $config['chars']['size'], 0, $config['chars']['start_x'], $config['chars']['start_y'], $captcha_text_color, $font_path, $captcha_code); return $target_layer; } public function renderCaptchaImage($imageData): void { header("Content-type: image/jpeg"); imagejpeg($imageData); } public function validateCaptcha($formData): bool { $isValid = false; $capchaSessionData = $this->getSession(); if ($capchaSessionData == $formData) { $isValid = true; } return $isValid; } private function hexToRgb($hex): array { return sscanf($hex, "#%02x%02x%02x"); } }