<?php
/**
* @package RSForm!Pro
* @copyright (C) 2020 www.rsjoomla.com
* @license GPL, http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
class plgSystemRsfpcleantalk extends CMSPlugin
{
protected $autoloadLanguage = true;
protected function getTable()
{
return Table::getInstance('RSForm_Cleantalk', 'Table');
}
public function onRsformFormSave($form)
{
$data = Factory::getApplication()->input->post->get('cleantalk', array(), 'array');
$data['form_id'] = $form->FormId;
$data['merge_vars'] = array();
$form = $this->getTabForm();
if ($fields = $form->getFieldset('merge'))
{
foreach ($fields as $field)
{
$data['merge_vars'][$field->fieldname] = isset($data[$field->fieldname]) ? $data[$field->fieldname] : '';
}
}
$row = $this->getTable();
if (!$row)
{
return false;
}
return $row->save($data);
}
protected function getTabForm()
{
Form::addFormPath(__DIR__ . '/forms');
$form = Form::getInstance( 'plg_system_rsfpcleantalk.tab', 'tab', array('control' => 'cleantalk'), false, false);
return $form;
}
public function onRsformBackendFormCopy($args)
{
$formId = $args['formId'];
$newFormId = $args['newFormId'];
if ($row = $this->getTable())
{
if ($row->load($formId))
{
if (!$row->bind(array('form_id' => $newFormId)))
{
return false;
}
if (!$row->check())
{
return false;
}
return $row->store();
}
}
}
public function onRsformBackendAfterShowFormEditTabs()
{
$formId = Factory::getApplication()->input->getInt('formId');
$row = $this->getTable();
if (!$row)
{
return false;
}
$row->load($formId);
$form = $this->getTabForm();
$data = $row->getProperties();
$data['merge_vars'] = array();
if ($fields = $form->getFieldset('merge'))
{
if (is_array($row->merge_vars))
{
foreach ($row->merge_vars as $key => $value)
{
$data[$key] = $value;
}
}
}
$form->bind($data);
?>
<div id="cleantalkdiv">
<fieldset class="form-horizontal">
<legend class="rsfp-legend"><?php echo Text::_('PLG_SYSTEM_RSFPCLEANTALK_INTEGRATION'); ?></legend>
<?php echo $form->renderFieldset('params'); ?>
<legend class="rsfp-legend"><?php echo Text::_('PLG_SYSTEM_RSFPCLEANTALK_MERGE_VARS'); ?></legend>
<?php echo $form->renderFieldset('merge'); ?>
</fieldset>
</div>
<?php
}
public function onRsformBackendAfterShowFormEditTabsTab()
{
?>
<li><a href="javascript: void(0);" id="cleantalk"><span class="rsficon rsficon-text-color"></span><span class="inner-text"><?php echo Text::_('PLG_SYSTEM_RSFPCLEANTALK_INTEGRATION'); ?></span></a></li>
<?php
}
public function onRsformFrontendBeforeFormDisplay($args)
{
$formId = $args['formId'];
$formLayout = &$args['formLayout'];
/* @var $row TableRSForm_Cleantalk */
$row = $this->getTable();
if (!$row)
{
return false;
}
if ($row->load(array('form_id' => $formId, 'published' => 1)))
{
$session = Factory::getSession();
$name = 'plg_rsfpcleantalk.formId' . $formId . '.ct_submit_time';
if (!$session->get($name, 0))
{
$session->set($name, time());
}
$formLayout = str_replace('</form>', '<input type="hidden" name="js_on" value="0" />'."\n".'</form>', $formLayout);
// Create the script
$script = <<<EOS
document.addEventListener('DOMContentLoaded', function() {
var form = RSFormPro.getForm({$formId});
if (form) {
var date = new Date();
form.elements['js_on'].value = date.getFullYear();
}
});
EOS;
RSFormProAssets::addScriptDeclaration($script);
RSFormProAssets::addScript('https://moderate.cleantalk.org/ct-bot-detector-wrapper.js');
}
}
public function onRsformFrontendBeforeFormValidation($args)
{
$post = $args['post'];
$formId = (int) $post['formId'];
$app = Factory::getApplication();
$task = strtolower($app->input->get('task', ''));
$option = strtolower($app->input->get('option', ''));
$isAjax = $option == 'com_rsform' && $task == 'ajaxvalidate';
/* @var $row TableRSForm_Cleantalk */
$row = $this->getTable();
if (!$row)
{
return false;
}
if ($row->load(array('form_id' => $formId, 'published' => 1)))
{
$session = Factory::getSession();
$name = 'plg_rsfpcleantalk.formId' . $formId . '.ct_submit_time';
$emailFieldId = false;
try
{
$data = array();
$components = array();
if ($row->merge_vars)
{
foreach ($row->merge_vars as $tag => $field)
{
if (empty($tag))
{
continue;
}
// Grab the field ID so we can set it as invalid below
$components[] = RSFormProHelper::getComponentId($field, $formId);
if ($tag === 'sender_email')
{
$emailFieldId = end($components);
}
if (!isset($post[$field]))
{
$post[$field] = '';
}
if (is_array($post[$field]))
{
$post[$field] = implode(',', $post[$field]);
}
$data[$tag] = $post[$field];
}
}
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/cleantalk/autoload.php';
$ct_request = new \Cleantalk\CleantalkRequest();
$ct_request->auth_key = RSFormProHelper::getConfig('cleantalk.key');
$ct_request->agent = 'php-api';
$ct_request->sender_ip = \Cleantalk\CleantalkHelper::ip_get(array('real'), false);
$ct_request->submit_time = time() - (int) $session->get($name, 0);
$ct_request->js_on = $app->input->post->getInt('js_on');
$ct_request->event_token = isset($_POST['ct_bot_detector_event_token']) ? $_POST['ct_bot_detector_event_token'] : null;
foreach ($data as $key => $value)
{
$ct_request->{$key} = $value;
}
$ct = new \Cleantalk\Cleantalk();
$ct->server_url = 'https://moderate.cleantalk.org';
$paths = array(
JPATH_SITE . '/libraries/vendor/composer/ca-bundle/res/cacert.pem',
JPATH_SITE . '/libraries/src/Http/Transport/cacert.pem',
JPATH_SITE . '/libraries/joomla/http/transport/cacert.pem'
);
foreach ($paths as $path)
{
if (file_exists($path))
{
$ct->ssl_path = $path;
break;
}
}
/* @var $ct_result \Cleantalk\CleantalkResponse */
$ct_result = $ct->isAllowMessage($ct_request);
if ($ct_result->errno !== 0)
{
throw new Exception($ct_result->errstr);
}
if (!$ct_result->allow)
{
throw new Exception($ct_result->comment, 500);
}
}
catch (Exception $e)
{
$app->enqueueMessage($e->getMessage(), 'error');
if ($e->getCode() == 500)
{
if (!empty($components))
{
$args['invalid'] = array_merge($args['invalid'], $components);
$args['invalid'] = array_unique($args['invalid']);
}
if ($emailFieldId && $isAjax)
{
$properties = &RSFormProHelper::getComponentProperties($emailFieldId);
$properties['VALIDATIONMESSAGE'] = $e->getMessage();
}
}
}
$session->clear($name);
}
}
public function onRsformBackendAfterShowConfigurationTabs($tabs)
{
$tabs->addTitle(Text::_('PLG_SYSTEM_RSFPCLEANTALK_CONFIGURATION'), 'form-cleantalk');
$tabs->addContent($this->showConfigurationScreen());
}
public function onRsformFormDelete($formId)
{
if ($row = $this->getTable())
{
$row->delete($formId);
}
}
public function onRsformFormBackup($form, $xml, $fields)
{
if ($row = $this->getTable())
{
if ($row->load($form->FormId))
{
$row->check();
$data = $row->getProperties();
unset($data['form_id']);
$xml->add('cleantalk');
foreach ($data as $property => $value)
{
$xml->add($property, $value);
}
$xml->add('/cleantalk');
}
}
}
public function onRsformFormRestore($form, $xml, $fields)
{
if (isset($xml->cleantalk))
{
$data = array(
'form_id' => $form->FormId
);
foreach ($xml->cleantalk->children() as $property => $value)
{
$data[$property] = (string) $value;
}
$row = $this->getTable();
$row->save($data);
}
}
public function onRsformBackendFormRestoreTruncate()
{
Factory::getDbo()->truncateTable('#__rsform_cleantalk');
}
private function loadFormData()
{
$data = array();
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__rsform_config'))
->where($db->qn('SettingName') . ' LIKE ' . $db->q('cleantalk.%', false));
if ($results = $db->setQuery($query)->loadObjectList())
{
foreach ($results as $result)
{
$data[$result->SettingName] = $result->SettingValue;
}
}
return $data;
}
protected function showConfigurationScreen()
{
ob_start();
Form::addFormPath(__DIR__ . '/forms');
$form = Form::getInstance( 'plg_system_rsfpcleantalk.configuration', 'configuration', array('control' => 'rsformConfig'), false, false );
$form->bind($this->loadFormData());
?>
<div id="page-cleantalk" class="form-horizontal">
<p><?php echo Text::_('PLG_SYSTEM_RSFPCLEANTALK_DONT_HAVE_ACCOUNT'); ?></p>
<p><a class="btn btn-primary" href="https://www.cleantalk.org" target="_blank"><?php echo Text::_('PLG_SYSTEM_RSFPCLEANTALK_CLICK_HERE_TO_GET_STARTED'); ?></a></p>
<?php
foreach ($form->getFieldsets() as $fieldset)
{
if ($fields = $form->getFieldset($fieldset->name))
{
foreach ($fields as $field)
{
// This is a workaround because our fields are named "cleantalk." and Joomla! uses the dot as a separator and transforms the JSON into [cleantalk][key] instead of [cleantalk.key].
echo str_replace('"rsformConfig[cleantalk][', '"rsformConfig[cleantalk.', $form->renderField($field->fieldname));
}
}
}
?>
</div>
<?php
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
}