<?php /** * @package RSForm! Pro * @copyright (C) 2007-2019 www.rsjoomla.com * @license GPL, http://www.gnu.org/copyleft/gpl.html */ defined('_JEXEC') or die; use Joomla\CMS\Router\Route; use Joomla\CMS\Factory; require_once JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/field.php'; class RSFormProFieldCaptcha extends RSFormProField { // backend preview public function getPreviewInput() { $type = $this->getProperty('IMAGETYPE', 'FREETYPE'); $caption = $this->getProperty('CAPTION', ''); if ($type == 'INVISIBLE') { $captchaOutput = '{hidden captcha}'; } else { $flow = $this->getProperty('FLOW', 'VERTICAL'); $componentId = $this->getProperty('componentId'); $refresh = $this->getProperty('SHOWREFRESH', 'NO'); $type = 'text'; // Start building the image HTML // Image source $src = Route::_('index.php?option=com_rsform&task=captcha&componentId='.$componentId.'&format=image&sid='.mt_rand()); // Image HTML $image = '<img'. ' src="'.$src.'"'. ' id="captcha'.$componentId.'"'. ' alt="'.$this->escape($caption).'"'. ' />'; // Start building the HTML input $input = '<input'; // Set the type & value $input .= ' type="'.$this->escape($type).'"'. ' value=""'; // Name & id $input .= ' id="captchaTxt'.$componentId.'"'; // Close the tag $input .= ' />'; // Add the refresh button $refreshBtn = ''; if ($refresh) { $text = $this->getProperty('REFRESHTEXT', ''); $base = Route::_('index.php?option=com_rsform&task=captcha&componentId='.$componentId.'&format=image'); $onclick = "RSFormPro.refreshCaptcha('$componentId', '$base'); return false;"; $refreshBtn = ' <a href="javascript:void(0)" onclick="'.$onclick.'">'.$text.'</a>'; } $captchaOutput = $image.($flow == 'VERTICAL' ? '<br/>' :'').$input.$refreshBtn; } return $captchaOutput; } // functions used for rendering in front view protected function getImageInput() { $name = $this->getName(); $flow = $this->getProperty('FLOW', 'VERTICAL'); $caption = $this->getProperty('CAPTION', ''); $componentId = $this->getProperty('componentId'); $refresh = $this->getProperty('SHOWREFRESH', 'NO'); $attr = $this->getAttributes(); $type = 'text'; $additional = ''; // Start building the image HTML // Image source $src = Route::_('index.php?option=com_rsform&task=captcha&componentId='.$componentId.'&format=image&sid='.mt_rand()); require_once JPATH_SITE . '/components/com_rsform/helpers/captcha.php'; $captcha = new RSFormProCaptcha($componentId); $data = base64_encode($captcha->makeCaptcha()); $src = 'data:image/png;base64,' . $data; // Image HTML $image = '<img'. ' src="'.$src.'"'. ' id="captcha'.$componentId.'"'. ' alt="'.$this->escape($caption).'"'. ' />'; // Start building the HTML input $input = '<input'; // Parse Additional Attributes if ($attr) { foreach ($attr as $key => $values) { // @new feature - Some HTML attributes (type, size, maxlength) can be overwritten // directly from the Additional Attributes area if ($key == 'type' && strlen($values)) { ${$key} = $values; continue; } $additional .= $this->attributeToHtml($key, $values); } } // Set the type & value $input .= ' type="'.$this->escape($type).'"'. ' value=""'; // Name & id $input .= ' name="'.$this->escape($name).'"'. ' id="captchaTxt'.$componentId.'"'; // Additional HTML $input .= $additional; // Close the tag $input .= ' />'; // Add the refresh button $refreshBtn = ''; if ($refresh) { $text = $this->getProperty('REFRESHTEXT', ''); $base = Route::_('index.php?option=com_rsform&task=captcha&componentId='.$componentId.'&format=image'); $onclick = "RSFormPro.refreshCaptcha('$componentId', '$base'); return false;"; $refreshBtn = ' <a href="javascript:void(0)" '.$this->getRefreshAttributes().' onclick="'.$onclick.'">'.$text.'</a>'; } return $this->setFieldOutput($image, $input, $refreshBtn, $flow); } protected function setFieldOutput($image, $input, $refreshBtn, $flow) { // Vertical flow needs a <br /> tag return $image.($flow == 'VERTICAL' ? '<br/>' :'').$input.$refreshBtn; } protected function getInvisibleInput() { $componentId = $this->getProperty('componentId'); $words = $this->getWords(); $word = $words[array_rand($words, 1)]; $styles = $this->getStyles(); $style = $styles[array_rand($styles, 1)]; // Now we're going to shuffle the properties of the HTML tag $properties = array( 'type="text"', 'name="'.$word.'"', 'value=""', 'style="'.$style.'"', 'aria-hidden="true"', 'aria-label="do not use"', ); shuffle($properties); $session = Factory::getSession(); $session->set('com_rsform.captcha.captchaId'.$componentId, $word); return '<input '.implode(' ', $properties).' />'; } public function getFormInput() { $type = $this->getProperty('IMAGETYPE', 'FREETYPE'); if ($type == 'INVISIBLE') { return $this->getInvisibleInput(); } else { return $this->getImageInput(); } } // @desc A list of words that spam bots might auto-complete protected function getWords() { return array('Website', 'Email', 'Name', 'Address', 'User', 'Username', 'Comment', 'Message'); } // @desc A list of styles protected function getStyles() { return array( 'display: none !important', 'position: absolute !important; left: -4000px !important; top: -4000px !important;', 'position: absolute !important; left: -4000px !important; top: -4000px !important; display: none !important;', 'position: absolute !important; display: none !important;', 'display: none !important; position: absolute !important; left: -4000px !important; top: -4000px !important;' ); } // @desc All captcha textboxes should have a 'rsform-captcha-box' class for easy styling public function getAttributes() { $attr = parent::getAttributes(); if (strlen($attr['class'])) { $attr['class'] .= ' '; } $attr['class'] .= 'rsform-captcha-box'; return $attr; } protected function getRefreshAttributes() { $attr = array( 'class="rsform-captcha-refresh-button"' ); return implode(' ', $attr); } public function processValidation($validationType = 'form', $submissionId = 0) { // Skip directory editing since it makes no sense if ($validationType == 'directory') { return true; } $form = RSFormProHelper::getForm($this->formId); $captchaCode = Factory::getSession()->get('com_rsform.captcha.captchaId' . $this->componentId); $value = $this->getValue(); // Logged in users don't need to pass Captcha if this option is enabled on the form. if (Factory::getUser()->id && $form->RemoveCaptchaLogged) { return true; } if ($this->getProperty('IMAGETYPE') == 'INVISIBLE') { if (empty($captchaCode)) { return false; } if (Factory::getApplication()->input->post->get($captchaCode, '', 'raw')) { return false; } $words = $this->getWords(); foreach ($words as $word) { if (Factory::getApplication()->input->post->get($word, '', 'raw')) { return false; } } } else { if (empty($value) || empty($captchaCode) || $value != $captchaCode) { return false; } } return true; } public function isRequired() { return true; } }