Використання капчі

    Використання капчі

    За замовчуванням FormLister може використовувати модифіковану капчу MODX і Google Recaptcha. Також в наявності SmsCaptcha - для відправки форми необхідно ввести код, отриманий в смс-повідомленні (відправку повідомлення необхідно реалізовувати окремо).

    Для підключення необхідно вказати ім'я папки з файлами капчи (папки знаходяться в assets/snippets/FormLister/lib/captcha/) в параметрі &captcha.

    У параметрі & captchaParams задаються у вигляді масиву настройки капчі. Наприклад:

    &captchaParams=`{
    "width":200,
    "height":120
    }`

    Ім'я поля, в яке користувач вводить значення капчі, задається параметром captchaField (за замовчуванням - vericode). Правило валідації для цього поля створюється автоматично.

    Капча виводиться в шаблоні форми за допомогою плейсхолдера [+captcha+].

    modxCaptcha

    Модифікація стандартної капчі MODX.

    Налаштування:

    • Width і height - ширина і висота картинки з капчі (значення за замовчуванням - 100 і 60);
    • inline - формат виведення. Якщо значення параметра дорівнює 1, то в плейсхолдер [+captcha+] виводиться картинка в base64-форматі. Якщо 0, то виводиться посилання на файл connector.php, що генерує картинку. Значення за замовчуванням - 1;
    • connectorDir - шлях до папки з файлом connector.php, якщо параметр inline дорівнює 0. Значення за замовчуванням - assets/snippets/FormLister/lib/captcha/modxCaptcha/;
    • errorEmptyCode - текст повідомлення про помилку, якщо поле зі значенням капчі не заповнено. Значення за замовчуванням - "Введіть перевірочний код";
    • errorCodeFailed - текст повідомлення про помилку, якщо введено невірне значення капчі. Значення за замовчуванням - "Невірний код перевірки"

    reCaptcha

    Капча Google reCAPTCHA V2. На сторінці з формою повинен бути підключений скрипт:

    <script src='https://www.google.com/recaptcha/api.js'></script>

    Значення параметра captchaField має бути "g-recaptcha-response" (див. документацію).

    Налаштування:

    • secretKey, siteKey - ключі для доступу до api reCAPTCHA;
    • size, theme, badge, callback, expired_callback, tabIndex, type - див. документацію;
    • errorCodeFailed - текст повідомлення про помилку, якщо користувач не пройшов перевірку. Значення за замовчуванням - "Ви не пройшли перевірку"

    smsCaptcha

    Налаштування:

    • CodeLifeTime - термін дії введеного коду, секунд. Якщо користувач спробує ввести код до закінчення терміну, то буде виведено повідомлення errorCodeUsed. Значення за замовчуванням - 86400 (доба);
    • ErrorEmptyCode - повідомлення про помилку, якщо користувач отримав, але не ввів код. Значення за замовчуванням - "Введіть код авторизації";
    • ErrorCodeRequired - повідомлення про помилку, якщо користувач не запросив код. Значення за замовчуванням - "Отримайте код авторизації";
    • ErrorCodeFailed - повідомлення про помилку, якщо користувач ввів невірний код авторизації. Значення за замовчуванням - "Невірний код авторизації";
    • ErrorCodeExpired - повідомлення про помилку, якщо користувач не ввів отриманий код протягом заданого часу. Значення за замовчуванням - "Код авторизації минув, отримаєте новий";
    • ErrorCodeUsed - повідомлення про помилку, якщо користувач вже вводив код для поточної форми. Значення за замовчуванням - "Код авторизації вже використовувався".

    Щоб використовувати цю капчу необхідно попередньо створити таблицю в базі даних:

    <?php
    include_once(MODX_BASE_PATH.'assets/snippets/FormLister/lib/captcha/smsCaptcha/model.php');
    $sms = new \SmsModel($modx);
    $sms->createTable();

    Для відправки коду необхідно створити окрему форму і вказати в параметрі prepareProcess сніпет:

    <?php
    //видаляємо з номера телефону все, крім цифр
    $rawPhone = preg_replace('/[^\d]+/','',$data['phone']);
    //задаємо значення, за яким буде визначатися для якої форми генерується код
    $formid = 'basic';
    //в сесії будемо зберігати номер телефону, це потрібно для перевірки коду в основній формі, потім його можна використовувати в якихось цілях, наприклад прибрати з основної форми поле для введення телефону, а в листі використовувати телефон з сесії
    $session_key = $formid.'.smscaptcha';
    if (empty($rawPhone)) {
        $FormLister->setValid(false);
        $FormLister->addError('phone','phone','Невірний номер телефону');   
    } else {
        //завантажуємо клас для роботи з таблицею
        $sms = $FormLister->loadModel('SmsModel','assets/snippets/FormLister/lib/captcha/smsCaptcha/model.php');
        $flag = false;
        //перевіряємо, чи є в таблиці запис для заданого номера і ідентифікатора форми
        $data = $sms->getData('+'.$rawPhone,$formid);
        if ($data->getID()) {
            //якщо є і код не закінчився
            if ($sms->get('expires') > time()) {
                //дивимося, чи використаний код
                if ($sms->get('active')) {
                    $FormLister->addMessage('Ви вже використовували код.');
                } else {
                    $FormLister->addMessage('Код вже був відправлений. Зачекайте кілька хвилин перш ніж запросити новий.');
                }
            //якщо код закінчився, то видаляємо запис і дозволяємо видати новий
            } else {
                $sms->delete($sms->getID());
                $flag = true;
            }
        } else {
            $flag = true;
        }
        //якщо можна видати новий код
        if ($flag) {
            $code = mt_rand(1000,9999);
    
            //тут відправляється смс і результат поміщається в змінну $result
            /** 
             *  
             */ 
            $result = array('status'=>true);
    
            //перевіряємо чи відправлена смс
            if (is_array($result) && $result['status']) {
                //створюємо запис в таблиці, час життя коду - 3 хвилини
                $result = $sms->create()->fromArray(array(
                    'phone'=>('+'.$rawPhone),
                    'formid'=>$formid,
                    'expires'=>(time() + 60*3),
                    'ip'=> \APIhelpers::getUserIP(),
                    'code'=>$code
                ))->save(); 
                //якщо вийшло записати, то зберігаємо в сесію номер телефону
            if ($result) {
                $_SESSION[$session_key] = '+'.$rawPhone;
            } else {
                $FormLister->setValid(false);
                $FormLister->addMessage('Не вдалося відправити смс');
            }
        } else {
            //якщо не можна видати код, то забороняємо подальшу обробку форми
            $FormLister->setValid(false);
        }
    }
    ?>

    Повністю виклик FormLister:

    [!FormLister?
    &formid=`code`
    &submitLimit=`0`
    &protectSubmit=`0`
    &rules=`{
    "phone":{
        "required":"Обов'язково введіть номер телефону",
        "phone":"Введіть номер правильно"
    }
    }`
    &prepareProcess=`setSmsCaptcha`
    &captcha=`modxCaptcha`
    &formTpl=`@CODE:
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="well">
                <form class="form-horizontal" method="post">
                    <input type="hidden" name="formid" value="code">
    
                    <div class="form-group[+phone.errorClass+][+phone.requiredClass+]">
                        <label for="phone" class="col-sm-2 control-label">* Телефон</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" placeholder="+375 29 123 45 67" name="phone" value="[+phone.value+]">
                                [+phone.error+]
                        </div>
                    </div>
    [+form.messages+]
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-primary"><i class="glyphicon glyphicon-envelope"></i> Надіслати</button>
                        </div>
                    </div>
                    <img src="[+captcha+]">
                    <input name="vericode">
                        [+vericode.error+]
                </form>
            </div>
        </div>
    </div>`
    &successTpl=`@CODE:Код авторизації відправлений на номер [+phone.value+]. Термін дії коду - 3 хвилини.`
    !]