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. Но, на мой взгляд, это не слишком большое неудобство. Во-первых, восстановить изменения займет от силы несколько минут, а во-вторых, разработчики не слишком часто обновляют продукт. Тем не менее - будьте внимательны.

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


© 2011-2017 ogri.me
Использование и перепечатка материалов сайта разрешены и приветствуются. Прямая индексируемая ссылка на используемую статью или, на худой конец, на сам сайт была бы хорошей наградой автору за его нелегкий труд.