ya ne robot ya robert

Небольшая предыстория. Я изначально использовал родную капчу компонента JComments - kcaptcha. В какой-то момент отключил ее, поскольку она раздражала комментаторов. Тут же в комментарии посыпался спам в гигантских количествах. Начал использовать CleanTalk - символически платный ($9 в год) плагин, защищающий от спамботов не только комментарии, но и вход/регистрацию, контакты и формы многих сторонних расширений. Спам было прекратился, но в последнее время эти гады настрополились слать мусорные комментарии, по форме маскирующиеся под нормальные и даже включающие в тексте заголовки статей. Их CleanTalk пока отфильтровать не может. Подобных "комментариев" стало приходить по 4-5 в день - не очень критично, да и убивать их легко прямо из уведомлений в почте. Но все же захотелось найти компромиссное решение проблемы - капчу, блокирующую не отлавливаемый CleanTalk-ом спам, но в то же время не раздражающую потенциальных комментаторов.

NO CAPTCHA reCAPTCHA от Гугла (или просто reCAPTCHA v2.0) подходит идеально. Начиная с Joomla 3.4 вторая версия включена в плагин reCAPTCHA, поставляемый с CMS. На время написания прошло почти два года с того релиза, а разрабы JComments так и не озаботились добавить поддержку этого плагина в свой компонент. Это никак не умаляет его достоинств - JComments был и остается лучшим бесплатным решением для комментариев на Джумла-сайте. Тем более что встроить сабж в комментарии достаточно просто своими силами. Для этого вам предстоит выполнить ряд несложных действий.

  1. Если ваш сайт не зарегистрирован в reCAPTCHA, заходите на страницу сервиса, кликаете на кнопку Get reCAPTCHA и добавляете доменное имя сайта. (Понятно, что нужно иметь аккаунт в Google.) Получаете два ключа - публичный и приватный. Замечу здесь, что если вы ранее пользовались первой версией reCAPTCHA, ключи для нее не подходят ко второй версии.
  2. В админке сайта заходим в Расширения | Extensions > Менеджер плагинов | Plugins, находим плагин CAPTCHA - reCAPTCHA и кликаем на его имя. В настройках плагина выбираем версию 2.0, вводим полученные от Гугла ключи, определяем стиль и размер. Если плагин выключен - включаем его. Сохраняем настройки.
  3. Редактируем два файла компонента JComments. Вам понадобится найти указанные оригинальные куски кода и заменить их на кастомизированные. Кликабельные скриншоты результатов сравнения в WinMerge с номерами строк и подсветкой изменений наглядно покажут, где, что и на что поменять (справа - изначальный код, слева - измененный).

    Изменение 1.

    Редактируем файл components\com_jcomments\tpl\default\tpl_form.php. Находим следующий кусок кода:

    if ($this->getVar('comments-form-captcha', 0) == 1) {
        $html = $this->getVar('comments-form-captcha-html');
        if ($html != '') {
          echo $html;
        } else {
          $link = JCommentsFactory::getLink('captcha');
    ?>
    <p>
      <span>
        <img class="captcha" onclick="jcomments.clear('captcha');" id="comments-form-captcha-image" src="<?php echo $link; ?>" width="121" height="60" alt="<?php echo JText::_('FORM_CAPTCHA'); ?>" /><br />
        <span class="captcha" onclick="jcomments.clear('captcha');"><?php echo JText::_('FORM_CAPTCHA_REFRESH'); ?></span><br />
        <input class="captcha" id="comments-form-captcha" type="text" name="captcha_refid" value="" size="5" tabindex="6" /><br />
      </span>
    </p>
    <?php
        }
    }
    ?>

    Заменяем на:

    if ($this->getVar('comments-form-captcha', 0) == 1) {
     
      $captchaEngine = 'recaptcha'; //or 'kcaptcha'
     
      if ($captchaEngine == 'recaptcha') {
        JPluginHelper::importPlugin('captcha');
        $dispatcher = JDispatcher::getInstance();
        $dispatcher->trigger('onInit','dynamic_recaptcha_1');
        $recaptcha = $dispatcher->trigger('onDisplay', array(null, 'dynamic_recaptcha_1', 'class=""'));
    ?>
    <div id="comments-form-captcha-holder">
      <?php echo (isset($recaptcha[0])) ? $recaptcha[0] : ''; ?>
    </div>
    <?php	
      } else if ($captchaEngine == 'kcaptcha') {
        $html = $this->getVar('comments-form-captcha-html');
        if ($html != '') {
          echo $html;
        } else {
          $link = JCommentsFactory::getLink('captcha');
    ?>
    <p>
      <span>
        <img class="captcha" onclick="jcomments.clear('captcha');" id="comments-form-captcha-image" src="<?php echo $link; ?>" width="121" height="60" alt="<?php echo JText::_('FORM_CAPTCHA'); ?>" /><br />
        <span class="captcha" onclick="jcomments.clear('captcha');"><?php echo JText::_('FORM_CAPTCHA_REFRESH'); ?></span><br />
        <input class="captcha" id="comments-form-captcha" type="text" name="captcha_refid" value="" size="5" tabindex="6" /><br />
      </span>
    </p>
    <?php
        }
      }
    }
    ?>

    Результат сравнения:

    Интегрируем reCAPTCHA v2 (NO CAPTCHA) в JComments - кастомизация 1

    Изменение 2

    Редактируем код файла components\com_jcomments\jcomments.ajax.php. Здесь заменить предстоит всего одну строчку:

    $captchaEngine = $config->get('captcha_engine', 'kcaptcha');

    Код для замены:

    $captchaEngine = 'recaptcha'; //or 'kcaptcha'
     
    if ($captchaEngine == 'recaptcha') {
      $post = JRequest::get('post');  
      JPluginHelper::importPlugin('captcha');
      $dispatcher = JDispatcher::getInstance();
      $result = $dispatcher->trigger('onCheckAnswer', $post['recaptcha_response_field']);
      $response->addScript('grecaptcha.reset();');
     
      if (!in_array(true, $result, true)) {
        self::showErrorMessage(JText::_('ERROR_RECAPTCHA_V2'), 'captcha');
        return $response;
      }
    } else

    Результат сравнения:

    Интегрируем reCAPTCHA v2 (NO CAPTCHA) в JComments - кастомизация 2

  4. Если комментатор забыл кликнуть на капчу, всплывает сообщение об ошибке. Для текста сообщения по умолчанию используется константа ERROR_CAPTCHA из языкового файла компонента. Ее значение - "Пожалуйста, введите код изображенный на картинке!". Поскольку никакой картинки с кодом теперь нет, я заменил сообщение на более подходящее - "Пожалуйста, подтвердите, что вы не робот!" и присвоил его новой константе ERROR_RECAPTCHA_V2. Почему я решил ввести новую языковую константу, а не переопределить значение уже имеющейся, а также - как и куда ее добавить, разъясняется в следующей статье.
  5. Чтобы органично вписать капчу в блок комментария на странице, задайте стиль элемента <div id="comments-form-captcha-holder"> в файле стилей вашего активного шаблона. Мне, например, оказалось достаточно выровнять по горизонтали и вертикали, для чего я добавил в css-файл моего шаблона следующий код:
    div#comments-form-captcha-holder {
        margin-top: 16px !important;
        margin-bottom: 20px !important;
    }
  6. Чтобы включить вывод капчи для соответствующих групп пользователей, открываем меню Компоненты | Components > JComments, заходим в Настройки | Settings, после чего кликаем на закладке Права | Permissions. Для выбранных групп пользователей (я рекомендую для ВСЕХ) отмечаем галку Защита от спамботов (CAPTCHA) | Enable CAPTCHA. Во вкладке же Вид | Layout в выпадающем списке CAPTCHA остается выбранным единственное значение - KCAPTCHA. Здесь это ни на что не влияет, выбор же между старой kcaptcha и новой удобной reCAPTCHA v2.0 осуществляется в измененном коде. Если по какой-либо причине вам захочется вернуться к родной капче компонента, просто измените строки
    $captchaEngine = 'recaptcha'; //or 'kcaptcha'
    в обоих файлах на такие:
    $captchaEngine = 'kcaptcha'; //or 'recaptcha'

В заключение напомню, что кастомизации придется восстанавливать в случае выхода новых билдов или версий компонента JComments. Но, на мой взгляд, это не слишком большое неудобство. Во-первых, восстановить изменения займет от силы несколько минут, а во-вторых, разработчики не слишком часто обновляют продукт. Тем не менее - будьте внимательны.

Комментарии  

Oleg
0 # Oleg 29.05.2017 16:12
Супер! Благодарю, выручил :-| :-)
Ответить | Ответить с цитатой | Цитировать
Ogri
0 # Ogri 29.05.2017 20:35
Рад, что пригодилось! На здоровье.
Ответить | Ответить с цитатой | Цитировать
ProtectYourSite
0 # ProtectYourSite 03.06.2017 04:15
А чем не устраивает уже готовый вариант с рекапчей и не надо лезть в код:
?
Ответить | Ответить с цитатой | Цитировать
ProtectYourSite
0 # ProtectYourSite 03.06.2017 04:16
Кабы только работало нормально комментирование)
Ответить | Ответить с цитатой | Цитировать
Ogri
0 # Ogri 04.06.2017 10:06
Готовый вариант - не с рекапчей, а с kcaptcha, где нужно вводить целую кучу букв и цифр. Раздражает многих, включая меня самого. Здесь же - один клик на чекбокс "Я не робот".
Ответить | Ответить с цитатой | Цитировать
ProtectYourSite
0 # ProtectYourSite 04.06.2017 10:37
Цитирую Ogri:
Готовый вариант - не с рекапчей, а с kcaptcha, где нужно вводить целую кучу букв и цифр. Раздражает многих, включая меня самого. Здесь же - один клик на чекбокс "Я не робот".

Давно интегрирован вариант с выбором капчи - kcaptcha или рекапча) если погуглить, то можно найти ссылку на архив, там решены и другие проблемы ( к примеру с пхп 7)
Ответить | Ответить с цитатой | Цитировать
Ogri
0 # Ogri 04.06.2017 13:14
Перед написанием статьи я хорошенько погуглил и ничего такого не нашел. Что же касается правки кода - см. последний абзац статьи. Я вообще достаточно кардинально перепахал компонент - прикрутил разбивку комментариев на страницы в случае древовидного вывода. (Надеюсь в ближайшем будущем поделиться методикой.) И последний аргумент: метод может быть полезен просто как пример для изучения.

Тем не менее, буду благодарен, если вы поделитесь ссылкой на упомянутый вами архив.
Ответить | Ответить с цитатой | Цитировать
ProtectYourSite
0 # ProtectYourSite 05.06.2017 04:34
Ссылки режутся, поэтому как-то так:

github.com / exstreme / Jcomments-Recaptcha2

Единственное, пока не знаю, как быть с подгрузкой капчи, если выставить: Настройки -> Вид -> Форма ... -> По умолчанию -> "Скрыть"
Разбивка на страницы - хорошая идея, видел на форуме не хватало некоторым.
Ответить | Ответить с цитатой | Цитировать
Deny
0 # Deny 19.06.2017 13:25
Спасибо большое за хак. Реально помог. Я то эти боты замотали в дребезги. А буковки юзеры вводить не хотят. А теперь самое то.

И еще можно поинтересоваться? А когда вы планируете статью (и планируете ли вообще) о том как сделать постраничную навигацию при древовидном отображении комментариев?
Ответить | Ответить с цитатой | Цитировать
Ogri
+1 # Ogri 19.06.2017 13:42
Спасибо за спасибо! :-|

Да, планирую. Там дофига изменений в коде получилось, думаю не углубляться в детали, а просто выложить архив с модифицированными файлами и дать сжатую инструкцию. Раз уж возник интерес от читателя, теперь подвину в приоритетах повыше. Скоро будет.
Ответить | Ответить с цитатой | Цитировать

Добавить комментарий