0

It's the First time that I use SP Page Builder component with Joomla. I want to use their contact form, but it doesn't support Google ReCaptcha. I'm good enough with coding to thought that I could manually add it into : /com_sppagebuilder/addons/ajax_contact/site.php and get it to work. I did add : <div class="g-recaptcha" data-sitekey="My_Key"></div>; And the Joomla ReCaptcha plugin is activated. I didn't know if I had to, but I added <script src='https://www.google.com/recaptcha/api.js'></script> into the head tag. With this the ReCaptcha is showing fine.

My problem is with the validation. I did try to add some validation code in the site.php but I believe SP Page Builder uses JFactory::getMailer(); to get the email ready and send it, and I don't know anything about that.

Thus, I do not know where I can add my ReCaptcha validation code, and as I did find few versions of that code online, I really don't know which one to use. I've been searching everywhere for some answers to how to do this verification... and I tried many things, but it's still not working.

Can anyone help me through this one ?

Thank you very much !

EDIT

I think my question is not clear enough :

I want to add Recaptcha, that is already working fine in other forms on my website (so it's not a configuration with Joomla problem). I want to use the following SP Page Builder contact form and not a RSFormPro as on the rest of the Website. The validation process should be done around this section, but I tried to add the Google validation code, and I tried a few versions of it I found around the Internet, and it's not working at all :

public static function getAjax() {
    $input = JFactory::getApplication()->input;
    $mail = JFactory::getMailer();

    //inputs
    $inputs             = $input->get('data', array(), 'ARRAY');

    foreach ($inputs as $input) {

        if( $input['name'] == 'recipient' ) {
            $recipient          = base64_decode($input['value']);
        }

        if( $input['name'] == 'email' ) {
            $email          = $input['value'];
        }

        if( $input['name'] == 'name' ) {
            $name           = $input['value'];
        }

        if( $input['name'] == 'subject' ) {
            $subject            = $input['value'];
        }

        if( $input['name'] == 'message' ) {
            $message            = nl2br( $input['value'] );
        }
    }

    /*Try at the validation*/
    $captcha_plugin = JFactory::getConfig()->get('captcha');
    if ($captcha_plugin != '0') {
    $captcha = JCaptcha::getInstance($captcha_plugin);
    $field_id = 'google-recaptcha';
     print $captcha->display($field_id, $field_id, 'g-recaptcha');
    }


    $sender = array($email, $name);
    $mail->setSender($sender);
    $mail->addRecipient($recipient);
    $mail->setSubject($subject);
    $mail->isHTML(true);
    $mail->Encoding = 'base64';
    $mail->setBody($message);

    if ($mail->Send()) {
        return '<span class="sppb-text-success">'. JText::_('COM_SPPAGEBUILDER_ADDON_AJAX_CONTACT_SUCCESS') .'</span>';
    } else {
        return '<span class="sppb-text-danger">'. JText::_('COM_SPPAGEBUILDER_ADDON_AJAX_CONTACT_FAILED') .'</span>';
    }
}

Any suggestions ?

Thank you !

StS
  • 49
  • 1
  • 11

3 Answers3

0

I have successfully added captcha to the Ajax contact form. Although the code still needs some improvements, Here is what I did:

See that I am using the n3tseznamcaptcha captcha plugin, I still need to implement the changes for other captchas to work (recaptcha,etc) but you can adapt it to your needs.

An SP Pagebuilder addon consists of two files, admin, and site. In the admin site I removed the default captcha, which lacks many security measures. Then in the site part I added the following:

function ajax_contact_addon($atts)
{
    global $formcaptcha;
    (...)
    if($formcaptcha) 
    {
            // TODO: Add Joomla's captcha:
            JPluginHelper::importPlugin('captcha');
            $dispatcher = JDispatcher::getInstance();

            // This will put the code to load CAPTCHA's JavaScript file into your <head>
            $dispatcher->trigger('onInit', 'dynamic_captcha_1');

            // This will return the array of HTML code.
            $captcha = $dispatcher->trigger('onDisplay', array(null, 'dynamic_captcha_1', 'class=""'));
            // I have only 1 recaptcha plugin enabled so the HTML is at 0 index, this will be improved in next version, following the contact component
            $output .= (isset($captcha[0])) ? $captcha[0] : '';
            $output .= '<div class="clearfix"></div><p></p>';
    }
    (...)
}

function ajax_contact_get_ajax() 
{
    global $formcaptcha;

    $jinput         = JFactory::getApplication()->input;
    $mail           = JFactory::getMailer();
    $config         = JFactory::getConfig();

    // TODO: CHECK CAPTCHA and add a Helper Class to get the captchas fields
    $captchaset = 'n3tseznamcaptcha';
    if ($captchaset === 'n3tseznamcaptcha')
    {   
        $captcha_field_hash = 'n3t_seznam_captcha_hash';
        $captcha_field_answer = 'n3t_seznam_captcha';
    }

    //inputs
    $inputs             = $jinput->get('data', array(), 'ARRAY');
    foreach ($inputs as $input) 
    {
            if( $input['name'] == 'title' ) 
            {
                $title                  = $input['value'];
            }
            if( $input['name'] == 'recipient' ) 
            {
                    $recipient      = base64_decode($input['value']);
            }

            if( $input['name'] == 'email' ) 
            {
                    $email          = $input['value'];
            }

            (...)

            if( $input['name'] == $captcha_field_hash ) 
            {
                    $captcha_hash   = $input['value'];
            }

            if( $input['name'] == $captcha_field_answer ) 
            {
                    $captcha_answer     = $input['value'];
            }
    }

    if($formcaptcha)
    {
            // get the plugin
            JPluginHelper::importPlugin('captcha');
            $dispatcher = JEventDispatcher::getInstance();

            // In order the plugin can check the code, we have to insert it into the request data:
            $jinput->set('n3t_seznam_captcha_hash', $captcha_hash);
            $jinput->set('n3t_seznam_captcha', $captcha_answer);

            // Here we check for the code:
            $res = $dispatcher->trigger('onCheckAnswer', $captcha_answer);

            if(!$res[0])
            {
                    // There is a problem with pagebuilder cache and captchas, so we need to clean the cache, to renew the captcha code:
                    $cache = JFactory::getCache('page');
                    $cache->clean();
                    return '<span class="pb-text-danger">'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_FORM_WRONG_CAPTCHA') .'</span>';
            }
}

}

I think that's all. Hope it helps you to find out.

spacebiker
  • 3,777
  • 4
  • 30
  • 49
  • This help a lot ! I'm still working on adapting it for Google's Captcha, I'll let you know if it works out :) – StS May 10 '17 at 17:18
  • Well... I must really suck at this because I really don't get what to put instead of : `$captchaset = 'n3tseznamcaptcha'; if ($captchaset === 'n3tseznamcaptcha') { $captcha_field_hash = 'n3t_seznam_captcha_hash'; $captcha_field_answer = 'n3t_seznam_captcha'; }` and instead of : `$jinput->set('n3t_seznam_captcha_hash', $captcha_hash); $jinput->set('n3t_seznam_captcha', $captcha_answer); $res = $dispatcher->trigger('onCheckAnswer', $captcha_answer);` In order to get my google ReCaptcha to work :/ – StS May 10 '17 at 17:54
  • The problem here implementing the installed captcha is that the ajax form does not fill the get parameters, it fills the POST variable and returns the AJAX response , therefor the plugin would never work, so what we have to do is get those values from the generated captcha fields and pass it to jinput (JFactory::getApplication->input) so that when the plugin is fired it can retrieve those values and check if they are right or wrong, but every captcha has its own fields so we need to find out which one we are using to read those values I'll add an edit in my answer for recaptcha plugin to work – spacebiker May 10 '17 at 22:10
0

So here you have the complete solution. Note that I changed a few things in the admin side too. This version will display and validate the default captcha selected in Joomla config, but it will only work for recaptcha and n3tsezam.. other should be added manually. The reason is that this addon does not add the challenge and response fields in the request, which the captcha plugins use for validation, therefor we need to retrieve it and write to the jinput within our ajax function (ajax_contact_get_ajax), and what complicates the whole thing is that every captcha plugin use different fields. Anyway.. if you need any other captcha plugin just can add it to the switch and you should be done.

function ajax_contact_addon($atts) {

        extract(AddonAtts(array(
                "title"             => '',
                "show_title"                    => '',
                "heading_selector"      => 'h3',
                "title_fontsize"        => '',
                "title_fontweight"      => '',
                "title_text_color"      => '',
                "title_margin_top"      => '',
                "title_margin_bottom"           => '',  
                "recipient_email"       => '',
                "formcaptcha"           => '',
                "class"             => '',
                ), $atts));

        JHtml::script('media/com_pagebuilder/js/ajax-contact.js');        

//      There is a problem with pagebuilder cache and captchas
        $cache = JFactory::getCache('page');
        $cache->clean();

        $output  = '<div class="pb-addon pb-addon-ajax-contact ' . $class . '">';

        if(boolval($show_title) && $title) 
        {

                $title_style = '';
                if($title_margin_top !='') $title_style .= 'margin-top:' . (int) $title_margin_top . 'px;';
                if($title_margin_bottom !='') $title_style .= 'margin-bottom:' . (int) $title_margin_bottom . 'px;';
                if($title_text_color) $title_style .= 'color:' . $title_text_color  . ';';
                if($title_fontsize) $title_style .= 'font-size:'.$title_fontsize.'px;line-height:'.$title_fontsize.'px;';
                if($title_fontweight) $title_style .= 'font-weight:'.$title_fontweight.';';

                $output .= '<'.$heading_selector.' class="pb-addon-title" style="' . $title_style . '">' . $title . '</'.$heading_selector.'>';
        }

        $output .= '<div class="pb-addon-content">';
        $output .= '<form class="pb-ajax-contact-form">';

        $output .= '<div class="pb-form-group">';
        $output .= '<input type="text" name="name" class="pb-form-control" placeholder="'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_NAME') .'" required="required">';
        $output .= '</div>';

        $output .= '<div class="pb-form-group">';
        $output .= '<input type="email" name="email" class="pb-form-control" placeholder="'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_EMAIL') .'" required="required">';
        $output .= '</div>';

        $output .= '<div class="pb-form-group">';
        $output .= '<input type="text" name="subject" class="pb-form-control" placeholder="'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_SUBJECT') .'" required="required">';
        $output .= '</div>';

        $output .= '<div class="pb-form-group">';
        $output .= '<textarea type="text" name="message" rows="5" class="pb-form-control" placeholder="'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_MESSAGE') .'" required="required"></textarea>';
        $output .= '</div>';

        if($formcaptcha) 
        {
                JPluginHelper::importPlugin('captcha');
                $dispatcher = JDispatcher::getInstance();
                $dispatcher->trigger('onInit', 'dynamic_captcha_1');

                $captchas = $dispatcher->trigger('onDisplay', array(null, 'dynamic_captcha_1', 'class=""'));
                $index = 0;

                foreach (JPluginHelper::getPlugin('captcha') as $plugin)
                {
                        if (JFactory::getApplication()->get('captcha', '0') === $plugin->name)
                        {
                                $captcha = $captchas[$index];
                                break;
                        }
                        $index++;
                }
                $output .= (isset($captcha)) ? $captcha : '';
                $output .= '<div class="clearfix"></div><p></p>';
        }

        $output .= '<input type="hidden" name="recipient" value="'. base64_encode($recipient_email) .'">';
        $output .= '<input type="hidden" name="title" value="'. $title .'">';

        $output .= '<button type="submit" class="btn btn-default"><i class="fa"></i> '. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_SEND') .'</button>';

        $output .= '</form>';

        $output .= '<div style="display:none;margin-top:10px;" class="pb-ajax-contact-status"></div>';

        $output .= '</div>';

        $output .= '</div>';

        return $output;

}

function ajax_contact_get_ajax() 
{
        $config                         = JFactory::getConfig();
        $jinput             = JFactory::getApplication()->input;
        //inputs
        $inputs             = $jinput->get('data', array(), 'ARRAY');

        $mail               = JFactory::getMailer();

        // TODO: Find the way to check if captcha is enabled in the addon
        $formcaptcha = true;
        $message = "";

        // TODO: CHECK CAPTCHA and add a Helper Class to get the captchas
        switch (JFactory::getApplication()->get('captcha', '0'))
        {
            case 'recaptcha':
                // v.1:
                //$captcha_challenge_field = 'recaptcha_challenge_field';
                //$captcha_answer_field = 'recaptcha_response_field';
                // v.2:
                $captcha_challenge_field = '';
                $captcha_answer_field = 'g-recaptcha-response';
                break;
            case 'n3tseznamcaptcha':
                $captcha_challenge_field = 'n3t_seznam_captcha_hash';
                $captcha_answer_field = 'n3t_seznam_captcha';
                break;
            default:
                // disable captcha as we could not find the right fields
                $formcaptcha = false;
        }

        foreach ($inputs as $input) 
        {

                if( $input['name'] == 'title' ) 
                {
                        $title                  = $input['value'];
                }
                if( $input['name'] == 'recipient' ) 
                {
                        $recipient      = base64_decode($input['value']);
                }

                if( $input['name'] == 'email' ) 
                {
                        $email          = $input['value'];
                }

                if( $input['name'] == 'name' ) 
                {
                        $name           = $input['value'];
                }

                if( $input['name'] == 'subject' ) 
                {
                        $subject            = $input['value'];
                }

                if( $input['name'] == 'message' ) 
                {
                        $message            = nl2br( $input['value'] );
                }

                if( $input['name'] == $captcha_challenge_field ) 
                {
                        $captcha_challenge  = $input['value'];
                }

                if( $input['name'] == $captcha_answer_field ) 
                {
                        $captcha_answer     = $input['value'];
                }

        }

        $valid_captcha = true;
        if($formcaptcha)
        {
                // get the plugin
                JPluginHelper::importPlugin('captcha');
                $dispatcher = JEventDispatcher::getInstance();

                $jinput->set($captcha_challenge_field,  $captcha_challenge);
                $jinput->set($captcha_answer_field,     $captcha_answer);

                $res = $dispatcher->trigger('onCheckAnswer', $captcha_answer);

                $index = 0;
                foreach (JPluginHelper::getPlugin('captcha') as $plugin)
                {
                        if (JFactory::getApplication()->get('captcha', '0') === $plugin->name)
                        {
                                $valid_captcha = $res[$index];
                                break;
                        }
                        $index++;
                }
                if(!$valid_captcha)
                {
                    $msg = '<span class="pb-text-danger">'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_FORM_WRONG_CAPTCHA') .'</span>';                        
                }
        }

        if ($valid_captcha)
        {
                // We do not want to send the email as a fake user, it may cause spam problems
                $sender = array( 
                        $config->get( 'mailfrom' ),
                        $config->get( 'fromname' ) 
                );

                $subject = (($title)? '['.$title.'] ' : '') . $subject;
                $message .= JText::sprintf('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_EMAIL_SIGNATURE', JUri::getInstance()->toString(),  JUri::getInstance());

                $mail->setSender($sender);
                $mail->addRecipient($recipient);
                $mail->setSubject($subject);
                $mail->AddReplyTo($email);
                $mail->isHTML(true);
                $mail->Encoding = 'base64'; 
                $mail->setBody($message);

                if ($mail->Send()) 
                {
                        $msg = '<span class="pb-text-success">'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_SUCCESS') .'</span>';
                } else {
                        $msg = '<span class="pb-text-danger">'. JText::_('COM_PAGEBUILDER_ADDON_AJAX_CONTACT_FAILED') .'</span>';
                }
        }

//      There is a problem with pagebuilder cache and captchas
        $cache = JFactory::getCache('page');
        $cache->clean();

        return $msg;

}
spacebiker
  • 3,777
  • 4
  • 30
  • 49
  • I tried your code into : /com_sppagebuilder/addons/ajax_contact/site.php, It's a step forward because now it block every contact messages instead of sending all of them XD I must be doing something wrong. – StS May 15 '17 at 12:49
0

That functionality is now integrated into SP Page Builder Contact Form Addon.

1) Grab the reCaptcha API keys from the console: https://www.google.com/recaptcha/admin get recaptcha keys

2) Enable reCaptcha plugin in Joomla's backend: Joomla Control Panel and navigate to Extensions > Plugins > captcha - reCaptcha enable recaptcha plugin

3) Enable reCaptcha in your Joomla configuration: Go to System > Global Configuration > Site Settings > Default Captcha set joomla configutarion for recaptcha

4) Go to your Contact Form (or create a new one) and enable captcha. Then choose "CAPTCHA - reCAPTCHA" in Captcha type selector. set recaptcha on form

After completing the above steps, if you don't see a reCAPTCHA box on the contact form frontend, it means that your template uses the old contact addon code. In most cases, you can safely take a backup and then delete the (bold) folder: templates\YOUR-TEMPLATE-NAME\sppagebuilder\addons\ajax_contact

All the info you need is available in this article: https://www.joomshaper.com/blog/google-recaptcha-joomla-contact-forms-integration

Pablo
  • 1,875
  • 1
  • 10
  • 11