Меняем капчу для eForm на капчу от яндекса

Получилось так, что пришлось закрыть папку manager от посторонних глаз с помощью .htaccess и соответственно сразу перестала работать капча во всех формах.
Долго не думая, пришла идея использовать капчу яндекса, да и лично мне она нравится))
Уверен что есть и другой способ не трогая файлов сниппетов и плагинов, но речь пойдёт именно о доработке оных))

Что делаем?

Первый способ

Заходим на api капчи яндекса tech.yandex.ru/cleanweb/ и получаем ключ.
И сохраните его куда нибудь, он ещё пригодится.
На этом, яндекс нам больше не нужен)))
В коде смотрите внимательно, вместо ВАШ_КЛЮЧ ставьте ключ полученный от яндекса.
находим файл assets/snippets/eform/eform.inc.php
находим строки
# check vericode
		if($vericode)

примерно на 183-190 строке
и меняем условие (от ковычки до ковычки)
if($vericode) {
			//add support for captcha code - thanks to Djamoer
			$code = $_SESSION['veriword'] ? $_SESSION['veriword'] : $_SESSION['eForm.VeriCode'];
			// YANDEX CAPTCHA
			$xmlResponse = file_get_contents('http://cleanweb-api.yandex.ru/1.0/check-captcha?key=ВАШ_КЛЮЧ&id='. $code .'&captcha='. $_SESSION['eForm.yandexcaptcha'] .'&value='. $fields['vericode']);
			$xml = simplexml_load_string($xmlResponse);
			if(isset($xml->ok)) {
				$fields['vericode'] = $code;
			}
			//\\ YANDEX CAPTCHA

			if($fields['vericode']!=$code) {
				$vMsg[count($vMsg)]=$_lang['ef_failed_vericode'];
				$rClass['vericode']=$invalidClass; //added in 1.4.4
			}
		}

далее находим уже на шестисотых (600) строках
// set vericode
	if($vericode) {

и меняем условие на
if($vericode) {
		$_SESSION['eForm.VeriCode'] = $fields['vericode'] = substr(uniqid(''),-5);
		//$fields['verimageurl'] = MODX_MANAGER_URL.'includes/veriword.php?rand='.rand();
		
		// YANDEX CAPTCHA
		$xmlResponse = file_get_contents('http://cleanweb-api.yandex.ru/1.0/get-captcha?key=ВАШ_КЛЮЧ&id='. $_SESSION['eForm.VeriCode'] .'&type=lite');
		$xml = simplexml_load_string($xmlResponse);
		$_SESSION['eForm.yandexcaptcha'] = (string)$xml->captcha;
		$fields['verimageurl'] = (string)$xml->url;
		//\\ YANDEX CAPTCHA
	}


вот и всё)
ещё раз обратите внимание на ваш ключ, не забудьте поменять в коде «ВАШ_КЛЮЧ» на именно ваш, полученный от яндекса.
На этом всё)
по настройкам вида капчи идём сюда tech.yandex.ru/cleanweb/doc/dg/concepts/get-captcha-docpage/
И как это выглядит


Второй способ

В файле assets/snippets/eform/eform.inc.php находим

	// set vericode
	if($vericode) {
		$_SESSION['eForm.VeriCode'] = $fields['vericode'] = substr(uniqid(''),-5);
		$fields['verimageurl'] = MODX_MANAGER_URL.'includes/veriword.php?rand='.rand();
	}

и меняем на

	// set vericode
	if($vericode) {
		$_SESSION['eForm.VeriCode'] = $fields['vericode'] = substr(uniqid(''),-5);
		$fields['verimageurl'] =  'assets/snippets/eform/captcha.php?rand='.rand();
	}

и затем добавляем в папку assets/snippets/eForm/
файл captcha.php с кодом

<?php
define('MODX_API_MODE', true);
include_once(dirname(__FILE__) . "../../../../index.php");

$c = new captcha_eForm;
$c->run();

class captcha_eForm {

	public function run() {
		$captcha = $this->generate_code();
		$this->img_code($captcha);
	}

	/**
	 * @return string
	 */
	private function generate_code() {
		//$chars = '1234567890абвгдеёжзийклмнопрстуфхцчшщъыэюя';
		$chars = '1234567890';
		$length = 5;
		$numChars = mb_strlen($chars, 'UTF-8');
		$str = '';
		for($i = 0; $i < $length; $i++) {
			$str .= mb_substr($chars, rand(1, $numChars) - 1, 1, 'UTF-8');
		}
		$array_mix = preg_split('//ui', $str, -1, PREG_SPLIT_NO_EMPTY);
		srand((float) microtime() * 1000000);
		shuffle($array_mix);
		return implode("", $array_mix);
	}

	/**
	 * @param $code
	 */
	private function img_code($code) {
		header("Pragma: no-cache");
		header("Content-Type:image/png");
		$_SESSION['veriword'] = $code;
		$im = imagecreate(210, 100);
		imagecolorallocatealpha($im, 255, 255, 255, 127);
		$color = imagecolorallocate($im, 0, 0, 0);
		$x = 10;
		for($i = 0; $i < strlen($code); $i++) {
			$letter = mb_substr($code, $i, 1, 'UTF-8');
			imagettftext($im, 70, rand(-10, 10), $x, 75, $color, "font.ttf", $letter);
			$x += 35;
		}
		imagepng($im);
		imagedestroy($im);
	}

}

и так же в папку кладём свой шрифт и переименовываем в font.ttf, либо скачиваем этот шрифт aCooperBlackOtl
Все размеры и отступы прописаны в функции img_code


P.S.
Если вдруг кому то нужно сделать так, чтобы картинку можно было обновить, без перезагрузки страницы, и если у вас подключен jQuery
код картинки в шаблоне формы

    <img id="verimageurl" src="[+verimageurl+]" alt="Код проверки" width="150" onclick="$(this).parent().load('/[~[*id*]~] #verimageurl');" title="Обновить изображение" style="cursor: pointer">

5 комментариев

avatar
Респект за такое решение! Намучился с капчей дефолтной, которая отказывалась работать на одном проекте, а эта запахала!
avatar
Тоже проверил, работает, спасибо за реализацию. Вопросик, не думали над кнопкой обновления капчи?
avatar
в принципе можно сделать, но над реализацией не думал
avatar
avatar
Спасибо работает! Мои варианты сложнее были (Ajax + снипит).
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.