AJAX Captcha в doit-cms

На многих cms captcha – стандартный модуль. В Doit-cms это не так, но благодаря гибкости нашей cms, мы с легкостью добавим модуль captcha на наш сайт. И так, начнем.

Для начала нам необходимо в папке storage создать папку captcha. В папке captcha создаем файл под названием index.php. Содержание файла будет следующим:

index.php

<?php      
      $letters = 'ABCDEFGKIJKLMNPQRSTUVWXYZ'; // символы, которые будут участвовать в формировании капчи
      $caplen = 6; // длина капчи (6 символов)
      $width = 164; $height = 40; // ширина и высота генерируемого изображения
      $font = 'myriadpro-cond.ttf'; // указывается файл шрифта
      $fontsize = 28; // размер шрифта
     
      header('Content-type: image/png');
     
      $im = imagecreatetruecolor($width, $height);
      imagesavealpha($im, true);
      $bg = imagecolorallocatealpha($im, 0, 0, 0, 127); // Создаем цвет фона. Это будет полностью прозрачный цвет
      imagefill($im, 0, 0, $bg);
     
      putenv( 'GDFONTPATH=' . realpath('.') );
     
      $captcha = '';
      for ($i = 0; $i < $caplen; $i++)
      {
        $captcha .= $letters[ rand(0, strlen($letters)-1) ];
        $x = ($width - 20) / $caplen * $i + 10;
        $x = rand($x, $x+4);
        $y = $height - ( ($height - $fontsize) / 2 );
        $curcolor = imagecolorallocate( $im, rand(0, 100), rand(0, 100), rand(0, 100) );
        $angle = rand(-25, 25); // Для текущего символа случайным образом генерируем его угол наклона
        imagettftext($im, $fontsize, $angle, $x, $y, $curcolor, $font, $captcha[$i]);
      }
      
      session_start();
      $_SESSION['captcha'] = $captcha;
     
      imagepng($im);
      imagedestroy($im);
      ?>

Этот файл будет отвечать за создание самого изображения captcha.

Так же в папку captcha необходимо загрузить файл шрифта, который будет использоваться при создании картинки. В нашем случае используется шрифт myriadpro-cond.ttf. Его вы сможете скачать в архиве, после статьи.

Использование CAPTCHA

Использовать captcha на сайте довольно таки просто. Рассмотрим на примере.

Допустим у нас имеется скаффолдинг reviews. Следовательно в папке app должна присутствовать папка mod_reviews. В папке mod_reviews у нас есть файлы _index.html и reviews.func.php.

Содержание файла _index.html должно быть следующим:

{{form 'reviews', 'ajax'=>true}}
<div class="notice"></div>
Имя:<br>
{{input 'name'}}<br>
Email:<br>
{{input 'email'}}<br>
Символы с картинки:
<div class="mycap"><img src="/storage/captcha/?sid=<?php echo rand(10000, 99999); ?>"  alt="" /></div>
{{input 'captcha'}}<br>
<input type="submit" />
{{/form}}

В данном файле находится форма, которая отправляет определенные данные на сервер. В нашем случае это Имя, Email и Символы с картинки (наша captcha).

Теперь необходимо принять и обработать эти данные. За это у нас отвечает файл reviews.func.php, а точнее function index().

reviews.func.php -> function index()

function index(){
        if(d()->validate('reviews')){
            $code = d()->params['captcha']; // Получаем введенную пользователем капчу
            if(isset($_SESSION['captcha']) && strtoupper($_SESSION['captcha']) == strtoupper($code)){ // если капча
                // введена верно
                // отправляем письмо
                d()->Mail->to('mailto@mail.ru');
                d()->Mail->subject('Письмо с сайта');
                d()->Mail->message(d()->mail_tpl_reviews());
                d()->Mail->send();
                // Пишем в форму нужный текст
                d()->Ajax->set_html('form','Письмо успешно отправлено!');
                d()->reload();
            }else{
                d()->add_notice('Неверно введены символы с картинки');
                d()->Ajax->set_html('.notice',d()->notice(array('style'=>'', 'class'=>'errorul')));
                d()->Ajax->set_html('.mycap','<img src="/storage/captcha/?sid='.rand(10000, 99999).'"  alt="" />');
                d()->Ajax->run_function('captcha_clean'); // чистим input captcha
                d()->reload();
            }
        }
        
        if(d()->notice()){
            d()->Ajax->set_html('.notice',d()->notice(array('style'=>'', 'class'=>'errorul')));
            d()->reload();
        }
        print d()->view();
}

Данная функция полностью обрабатывает все данные и если все введено верно, то отправляет письмо на почту.

Для корректной работы нам необходимо создать файл validator.init.ini. Содержание validator.init.ini будет следующим:

[validator.reviews.name]
required.message=Вы не ввели имя
[validator.reviews.email]
required.message=Вы не ввели электронную почту
[validator.reviews.captcha]
required.message=Вы не ввели символы с картинки

Этот файл отвечает за обязательное заполнение всех полей.

Так же необходимо создать файл mail.tpl.reviews.html, который будет отвечать за текст письма, отправленное по почте.

mail.tpl.reviews.html

<center><h1>Hello world!</h1></center>

Ну и на последок, в одном из js файлов, подключаемых к нашему сайту, необходимо добавить функцию captcha_clean(), которая отвечает за очищение поля captcha при неправильном ее вводе:

function captcha_clean(){
    $("#data_captcha").val("").focus();
}

На этом вроде все. Возможно я перемудрул, но пока это самый рациональный способ, который я нашел. =) Всем удачи.


Скачать весь "Исходный код"