<?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\MVC\Model\ListModel;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\Utilities\IpHelper;
class RsformModelSubmissions extends ListModel
{
public $_data = array();
public $firstFormId = 0;
public $allFormIds = array();
public $export = false;
public $rows = 0;
public $exportType = '';
public $stripLines = false;
public $multipleSeparator;
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array_merge(array_keys($this->getHeaders()), array_keys($this->getStaticHeaders()));
// Need these so that 'Filter Options' is shown
$config['filter_fields'][] = 'dateFrom';
$config['filter_fields'][] = 'dateTo';
$config['filter_fields'][] = 'language';
}
parent::__construct($config);
}
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.language');
$id .= ':' . $this->getState('filter.dateFrom');
$id .= ':' . $this->getState('filter.dateTo');
return parent::getStoreId($id);
}
protected function getListQuery()
{
$sortColumn = $this->getSortColumn();
$sortOrder = $this->getSortOrder();
$formId = $this->getFormId();
$filter = $this->getFilter();
$languageFilter = $this->getLang();
$isStaticHeader = in_array($sortColumn, array_keys($this->getStaticHeaders()));
$join = false;
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('s.*')
->from($db->qn('#__rsform_submissions', 's'))
->where($db->qn('s.FormId') . ' = ' . $db->q($formId));
// Only for export - export selected rows
if ($this->export && !empty($this->rows))
{
$query->where($db->qn('s.SubmissionId') . ' IN (' . implode(',', $db->q($this->rows)) . ')');
}
// Check if there's a filter (search) set
if (!$this->export)
{
if ($filter !== null && $filter !== '' && strlen($filter))
{
$or = array();
$join = true;
$escapedFilter = $db->q('%' . $db->escape($filter) . '%', false);
if (!preg_match('#([^0-9\-: ])#', $filter))
{
$or[] = $db->qn('s.DateSubmitted') . ' LIKE ' . $escapedFilter;
}
$or[] = $db->qn('s.Username') . ' LIKE ' . $escapedFilter;
$or[] = $db->qn('s.UserIp') . ' LIKE ' . $escapedFilter;
if ($isStaticHeader)
{
$or[] = $db->qn('sv.FieldValue') . ' LIKE ' . $escapedFilter;
}
else
{
$subquery = $db->getQuery(true)
->select($db->qn('SubmissionId'))
->from($db->qn('#__rsform_submission_values'))
->where($db->qn('FormId') . ' = ' . $db->q($formId))
->where($db->qn('FieldValue') . ' LIKE ' . $escapedFilter);
$or[] = $db->qn('s.SubmissionId') . ' IN (' . $subquery . ')';
}
$query->where('(' . implode(' OR ', $or) . ')');
}
if ($languageFilter)
{
$query->where($db->qn('s.Lang') . ' = ' . $db->q($languageFilter));
}
if ($from = $this->getDateFrom())
{
$query->where($db->qn('s.DateSubmitted') . ' >= ' . $db->q(Factory::getDate($from)->toSql()));
}
if ($to = $this->getDateTo())
{
$query->where($db->qn('s.DateSubmitted') . ' <= ' . $db->q(Factory::getDate($to)->toSql()));
}
}
// Order by static headers
if ($isStaticHeader)
{
$query->order($db->qn('s.' . $sortColumn) . ' ' . $db->escape($sortOrder));
}
else
{
$join = true;
if ($this->isOrderingPossible($sortColumn))
{
$query->where($db->qn('sv.FieldName') . ' = ' . $db->q($sortColumn));
}
$query->order($db->qn('sv.FieldValue') . ' ' . $db->escape($sortOrder));
}
if ($join)
{
$query->join('left', $db->qn('#__rsform_submission_values', 'sv') . ' ON (' . $db->qn('s.SubmissionId') . ' = ' . $db->qn('sv.SubmissionId') . ')')
->group(array($db->qn('s.SubmissionId')));
}
return $query;
}
public function isOrderingPossible($field)
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select($db->qn('SubmissionValueId'))
->from($db->qn('#__rsform_submission_values'))
->where($db->qn('FieldName') . ' = ' . $db->q($field))
->where($db->qn('FormId') . ' = ' . $db->q($this->getFormId()));
$db->setQuery($query);
return $db->loadResult();
}
public function getDateFrom()
{
return $this->getState('filter.dateFrom');
}
public function getDateTo()
{
return $this->getState('filter.dateTo');
}
public function getLang()
{
return $this->getState('filter.language');
}
public function getFilter()
{
return $this->getState('filter.search');
}
public function getSpecialFields()
{
return RSFormProHelper::getDirectoryFormProperties($this->getFormId(), true);
}
public function getFormProperties()
{
return RSFormProHelper::getForm($this->getFormId());
}
public function getSubmissions()
{
if (empty($this->_data))
{
$formId = $this->getFormId();
$app = Factory::getApplication();
$db = $this->getDbo();
$form = $this->getFormProperties();
$multipleSeparator = $form->MultipleSeparator;
if ($this->multipleSeparator !== null)
{
$multipleSeparator = $this->multipleSeparator;
}
$multipleSeparator = str_replace(array('\n', '\r', '\t'), array("\n", "\r", "\t"), $multipleSeparator);
if (empty($form))
{
return $this->_data;
}
$uploadFields = array();
$multipleFields = array();
$textareaFields = array();
$fieldTypes = $this->getSpecialFields();
if (isset($fieldTypes['uploadFields']))
{
$uploadFields = $fieldTypes['uploadFields'];
}
if (isset($fieldTypes['multipleFields']))
{
$multipleFields = $fieldTypes['multipleFields'];
}
if (isset($fieldTypes['textareaFields']))
{
$textareaFields = $fieldTypes['textareaFields'];
}
$db->setQuery("SET SQL_BIG_SELECTS=1")->execute();
$results = $this->_getList($this->getListQuery(), $this->getStart(), $this->getState('list.limit'));
foreach ($results as $result)
{
$this->_data[$result->SubmissionId] = array(
'SubmissionId' => $result->SubmissionId,
'FormId' => $result->FormId,
'DateSubmitted' => RSFormProHelper::getDate($result->DateSubmitted),
'UserIp' => $result->UserIp,
'Username' => $result->Username,
'UserId' => $result->UserId,
'Lang' => $result->Lang,
'confirmed' => $result->confirmed ? Text::_('RSFP_YES') : Text::_('RSFP_NO'),
'ConfirmedIp' => $result->ConfirmedIp,
'ConfirmedDate' => $result->ConfirmedDate ? RSFormProHelper::getDate($result->ConfirmedDate) : '',
'SubmissionValues' => array(),
);
}
$submissionIds = array_keys($this->_data);
if (!empty($submissionIds))
{
$must_escape = $app->input->get('view') == 'submissions' && $app->input->get('layout') == 'default';
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__rsform_submission_values'))
->where($db->qn('SubmissionId') . ' IN (' . implode(',', $db->q($submissionIds)) . ')');
$results = $db->setQuery($query)->loadObjectList();
foreach ($results as $result)
{
// Check if this is an upload field
if (in_array($result->FieldName, $uploadFields) && !empty($result->FieldValue) && !$this->export)
{
$files = RSFormProHelper::explode($result->FieldValue);
$values = array();
foreach ($files as $file)
{
$values[] = '<a href="index.php?option=com_rsform&task=submissions.viewfile&id='.$result->SubmissionValueId.'&file='.md5($file).'">'.RSFormProHelper::htmlEscape(basename($file)).'</a>';
}
$result->FieldValue = implode('<br />', $values);
}
else
{
// Check if this is a multiple field
if (in_array($result->FieldName, $multipleFields))
{
$result->FieldValue = str_replace("\n", $multipleSeparator, $result->FieldValue);
}
// Transform new lines
elseif ($form->TextareaNewLines && in_array($result->FieldName, $textareaFields))
{
if ($must_escape)
{
$result->FieldValue = RSFormProHelper::htmlEscape($result->FieldValue);
}
elseif ($this->exportType === 'csv' && !$this->stripLines)
{
$result->FieldValue = nl2br($result->FieldValue);
}
}
elseif ($must_escape)
{
$result->FieldValue = RSFormProHelper::htmlEscape($result->FieldValue);
}
}
$this->_data[$result->SubmissionId]['SubmissionValues'][$result->FieldName] = array(
'Value' => $result->FieldValue,
'Id' => $result->SubmissionValueId
);
}
Factory::getApplication()->triggerEvent('onRsformBackendManageSubmissions', array(array(
'formId' => $formId,
'submissions' => &$this->_data,
'export' => $this->export,
'escape' => $must_escape,
)));
}
unset($results);
}
return $this->_data;
}
public function getSubmission()
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__rsform_submissions'))
->where($db->qn('SubmissionId') . ' = ' . $db->q($this->getSubmissionId()));
return $db->setQuery($query)->loadObject();
}
protected function getSkippedFields()
{
$skippedFields = array(RSFORM_FIELD_BUTTON, RSFORM_FIELD_CAPTCHA, RSFORM_FIELD_HASHCASH, RSFORM_FIELD_PREVIEW, RSFORM_FIELD_FREETEXT, RSFORM_FIELD_SUBMITBUTTON);
$skippedFields = array_merge($skippedFields, RSFormProHelper::$captchaFields);
Factory::getApplication()->triggerEvent('onRsformBackendGetSkippedFields', array(&$skippedFields));
return $skippedFields;
}
public function getHeaders()
{
$db = Factory::getDbo();
$formId = $this->getFormId();
$query = $db->getQuery(true)
->select($db->qn('p.PropertyValue'))
->from($db->qn('#__rsform_components', 'c'))
->join('left', $db->qn('#__rsform_properties', 'p') . ' ON (' . $db->qn('c.ComponentId') . '=' . $db->qn('p.ComponentId') . ' AND ' . $db->qn('p.PropertyName') . ' = ' . $db->q('NAME') . ')')
->join('left', $db->qn('#__rsform_component_types', 'ct') . ' ON (' . $db->qn('c.ComponentTypeId') . '=' . $db->qn('ct.ComponentTypeId') . ')')
->where($db->qn('c.FormId') . ' = ' . $db->q($formId))
->where($db->qn('c.Published') . ' = ' . $db->q(1));
$query->where($db->qn('ct.ComponentTypeId') . ' NOT IN (' . implode(',', $db->q($this->getSkippedFields())) . ')');
$query->order($db->qn('c.Order'));
$headers = $db->setQuery($query)->loadColumn();
Factory::getApplication()->triggerEvent('onRsformBackendGetSubmissionHeaders', array(&$headers, $formId));
// Get labels
$results = array();
if ($headers)
{
foreach ($headers as $header)
{
$value = $header;
Factory::getApplication()->triggerEvent('onRsformBackendGetHeaderLabel', array(&$header, $formId));
$results[$value] = new RSFormProSubmissionHeader($value, $header, 0, $formId);
}
}
return $results;
}
public function getUnescapedFields()
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->qn('p.PropertyValue'))
->from($db->qn('#__rsform_components', 'c'))
->join('left', $db->qn('#__rsform_properties', 'p') . ' ON (' . $db->qn('c.ComponentId') . '=' . $db->qn('p.ComponentId') . ')')
->where($db->qn('c.FormId') . ' = ' . $db->q($this->getFormId()))
->where($db->qn('c.ComponentTypeId') . ' = ' . $db->q(RSFORM_FIELD_FILEUPLOAD))
->where($db->qn('p.PropertyName') . ' = ' . $db->q('NAME'));
$fields = $db->setQuery($query)->loadColumn();
Factory::getApplication()->triggerEvent('onRsformBackendManageSubmissionsCreateUnescapedFields', array(array(
'formId' => $this->getFormId(),
'fields' => &$fields
)));
return $fields;
}
public function getStaticHeaders()
{
$headers = array('SubmissionId', 'DateSubmitted', 'UserIp', 'Username', 'UserId', 'Lang');
if ($this->addConfirmedHeader())
{
$headers[] = 'confirmed';
$headers[] = 'ConfirmedIp';
$headers[] = 'ConfirmedDate';
}
$results = array();
foreach ($headers as $header)
{
$results[$header] = new RSFormProSubmissionHeader($header, Text::_('RSFP_' . $header), 1, $this->getFormId());
}
return $results;
}
public function addConfirmedHeader()
{
if ($form = $this->getFormProperties())
{
return (bool) $form->ConfirmSubmission;
}
return false;
}
public function getFormTitle()
{
$formId = $this->getFormId();
$db = $this->getDbo();
$query = $db->getQuery(true)
->select($db->qn('FormTitle'))
->from($db->qn('#__rsform_forms'))
->where($db->qn('FormId') . ' = ' . $db->q($formId));
$title = $db->setQuery($query)->loadResult();
if ($translations = RSFormProHelper::getTranslations('forms', $formId, RSFormProHelper::getCurrentLanguage($formId)))
{
if (isset($translations['FormTitle']))
{
$title = $translations['FormTitle'];
}
}
return $title;
}
public function getFormMultipleSeparator()
{
$formId = $this->getFormId();
$db = $this->getDbo();
$query = $db->getQuery(true)
->select($db->qn('MultipleSeparator'))
->from($db->qn('#__rsform_forms'))
->where($db->qn('FormId') . ' = ' . $db->q($formId));
return $db->setQuery($query)->loadResult();
}
public function getForms()
{
$mainframe = Factory::getApplication();
$db = Factory::getDbo();
$sortColumn = $mainframe->getUserState('com_rsform.forms.filter_order', 'FormId');
$sortOrder = $mainframe->getUserState('com_rsform.forms.filter_order_Dir', 'ASC');
$return = array();
$query = $db->getQuery(true)
->select($db->qn('FormId'))
->select($db->qn('FormTitle'))
->select($db->qn('Lang'))
->from($db->qn('#__rsform_forms'))
->order($db->qn($sortColumn) . ' ' . $db->escape($sortOrder));
if ($results = $db->setQuery($query)->loadObjectList())
{
foreach ($results as $result)
{
$lang = RSFormProHelper::getCurrentLanguage($result->FormId);
if ($lang != $result->Lang)
{
if ($translations = RSFormProHelper::getTranslations('forms', $result->FormId, $lang))
{
foreach ($translations as $field => $value)
{
if (isset($result->{$field}))
{
$result->{$field} = $value;
}
}
}
}
$return[] = HTMLHelper::_('select.option', $result->FormId, $result->FormTitle);
$this->allFormIds[] = $result->FormId;
}
if (!empty($results[0]->FormId))
{
$this->firstFormId = $results[0]->FormId;
}
}
return $return;
}
public function getSortColumn()
{
return $this->getState('list.ordering', 'DateSubmitted');
}
public function getSortOrder()
{
return $this->getState('list.direction', 'desc');
}
protected function populateState($ordering = null, $direction = null)
{
// We do this here because it overrides our setUserState() below
parent::populateState('DateSubmitted', 'desc');
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
$language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '');
$this->setState('filter.language', $language);
$app = Factory::getApplication();
$offset = $app->get('offset');
foreach (array('dateFrom', 'dateTo') as $date)
{
$value = $this->getUserStateFromRequest($this->context . '.filter.' . $date, 'filter_' . $date, '');
if (strlen($value))
{
// Test if date is valid
try
{
$value = Factory::getDate($value, $offset)->toSql();
}
catch (Exception $e)
{
$app->enqueueMessage($e->getMessage(), 'warning');
// Reset the value
$value = '';
}
}
$this->setState('filter.' . $date, $value);
$app->setUserState($this->context . '.filter.' . $date, $value);
}
}
public function getFormId()
{
$mainframe = Factory::getApplication();
if (empty($this->firstFormId))
{
$this->getForms();
}
$formId = $mainframe->getUserStateFromRequest('com_rsform.submissions.formId', 'formId', $this->firstFormId, 'int');
if ($formId && !in_array($formId, $this->allFormIds))
{
$formId = $this->firstFormId;
$mainframe->setUserState('com_rsform.submissions.formId', $formId);
}
return $formId;
}
public function getSubmissionId()
{
$cid = Factory::getApplication()->input->get('cid', array(), 'array');
if (is_array($cid))
{
$cid = (int) reset($cid);
}
else
{
$cid = (int) $cid;
}
return $cid;
}
public function getEditFields()
{
$mainframe = Factory::getApplication();
$db = $this->getDbo();
$isPDF = $mainframe->input->get('format') == 'pdf';
$cid = $this->getSubmissionId();
$return = array();
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/submissions.php';
$submission = RSFormProSubmissionsHelper::getSubmission($cid);
if (empty($submission))
{
$mainframe->redirect('index.php?option=com_rsform&view=submissions');
return $return;
}
if ($isPDF)
{
$query = $db->getQuery(true)
->select($db->qn('MultipleSeparator'))
->select($db->qn('TextareaNewLines'))
->from($db->qn('#__rsform_forms'))
->where($db->qn('FormId') . ' = ' . $db->q($submission->FormId));
$form = $db->setQuery($query)->loadObject();
$form->MultipleSeparator = str_replace(array('\n', '\r', '\t'), array("\n", "\r", "\t"), $form->MultipleSeparator);
}
$query = $db->getQuery(true);
$query->select($db->qn('p.PropertyValue'))
->select($db->qn('ct.ComponentTypeName'))
->select($db->qn('c.ComponentId'))
->from($db->qn('#__rsform_components','c'))
->join('left', $db->qn('#__rsform_properties','p').' ON '.$db->qn('p.ComponentId').' = '.$db->qn('c.ComponentId'))
->join('left', $db->qn('#__rsform_component_types','ct').' ON '.$db->qn('c.ComponentTypeId').' = '.$db->qn('ct.ComponentTypeId'))
->where($db->qn('c.FormId') . ' = ' . $db->q($submission->FormId))
->where($db->qn('p.PropertyName') . ' = ' . $db->q('NAME'))
->where($db->qn('c.Published') . ' = ' . $db->q(1))
->order($db->qn('c.Order') . ' ' . $db->escape('asc'));
// Skip some fields
$query->where($db->qn('ct.ComponentTypeId') . ' NOT IN (' . implode(',', $db->q($this->getSkippedFields())) . ')');
$fields = $db->setQuery($query)->loadObjectList();
if (empty($fields))
{
return $return;
}
$componentIds = array();
foreach ($fields as $field)
{
$componentIds[] = $field->ComponentId;
}
$properties = RSFormProHelper::getComponentProperties($componentIds);
foreach ($fields as $field)
{
$data = $properties[$field->ComponentId];
$name = $field->PropertyValue;
$new_field = array();
$new_field[0] = $name;
$new_field[3] = $name;
$value = isset($submission->values[$field->PropertyValue]) ? $submission->values[$field->PropertyValue] : '';
switch ($field->ComponentTypeName)
{
// skip this field for now, no need to edit it
case 'freeText':
continue 2;
break;
default:
if ($isPDF)
{
$new_field[1] = RSFormProHelper::htmlEscape($value);
}
else
{
if (strpos($value, "\n") !== false || strpos($value, "\r") !== false)
{
$new_field[1] = '<textarea style="width: 95%" class="rs_textarea" rows="10" cols="60" name="form['.$name.']">'.RSFormProHelper::htmlEscape($value).'</textarea>';
}
else
{
$new_field[1] = '<input class="rs_inp rs_80" size="105" type="text" name="form['.$name.']" value="'.RSFormProHelper::htmlEscape($value).'" />';
}
}
break;
case 'textArea':
if ($isPDF)
{
if ($form->TextareaNewLines && (!isset($data['WYSIWYG']) || $data['WYSIWYG'] == 'NO'))
{
$value = nl2br(RSFormProHelper::htmlEscape($value));
}
$new_field[1] = $value;
}
elseif (isset($data['WYSIWYG']) && $data['WYSIWYG'] == 'YES')
{
$new_field[1] = RSFormProHelper::WYSIWYG('form['.$name.']', RSFormProHelper::htmlEscape($value), '', 600, 100, 60, 10);
}
else
{
$new_field[1] = '<textarea style="width: 95%" class="rs_textarea" rows="10" cols="60" name="form['.$name.']">'.RSFormProHelper::htmlEscape($value).'</textarea>';
}
break;
case 'radioGroup':
case 'checkboxGroup':
case 'selectList':
if ($isPDF)
{
$new_field[1] = str_replace("\n", $form->MultipleSeparator, $value);
break;
}
$options = array();
if ($field->ComponentTypeName == 'radioGroup')
{
$data['SIZE'] = 0;
$data['MULTIPLE'] = 'NO';
$options[] = HTMLHelper::_('select.option', '', Text::_('COM_RSFORM_NO_VALUE'));
}
elseif ($field->ComponentTypeName == 'checkboxGroup')
{
$data['SIZE'] = 5;
$data['MULTIPLE'] = 'YES';
}
$value = RSFormProHelper::explode($value);
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/fields/fielditem.php';
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/fieldmultiple.php';
$f = new RSFormProFieldMultiple(array(
'formId' => $submission->FormId,
'componentId' => $field->ComponentId,
'data' => $data,
'value' => array('formId' => $submission->FormId, $data['NAME'] => $value),
'invalid' => false
));
if ($items = $f->getItems())
{
foreach ($items as $item)
{
$item = new RSFormProFieldItem($item);
if ($item->flags['optgroup'])
{
$options[] = HTMLHelper::_('select.option', '<OPTGROUP>', $item->label, 'value', 'text');
}
elseif ($item->flags['/optgroup'])
{
$options[] = HTMLHelper::_('select.option', '</OPTGROUP>', $item->label, 'value', 'text');
}
else
{
$options[] = HTMLHelper::_('select.option', $item->value, $item->label, 'value', 'text');
}
}
}
$attribs = array();
if ((int) $data['SIZE'] > 0)
{
$attribs[] = 'size="'.(int) $data['SIZE'].'"';
}
if ($data['MULTIPLE'] == 'YES')
{
$attribs[] = 'multiple="multiple"';
}
$attribs = implode(' ', $attribs);
$new_field[1] = HTMLHelper::_('select.genericlist', $options, 'form['.$name.'][]', $attribs, 'value', 'text', $value);
break;
case 'fileUpload':
if ($isPDF)
{
if (!empty($data['FILESSEPARATOR']))
{
$separator = str_replace(array('\n', '\r', '\t'), array("\n", "\r", "\t"), $data['FILESSEPARATOR']);
}
else
{
$separator = '<br />';
}
$new_field[1] = implode($separator, RSFormProHelper::explode($value));
break;
}
if ($value)
{
$files = RSFormProHelper::explode($value);
}
else
{
$files = array();
}
$new_field[1] = '<ul class="rsfp-multiupload-list">';
foreach ($files as $file)
{
$new_field[1] .= '<li><button type="button" class="btn btn-secondary btn-mini btn-sm" onclick="RSFormPro.removeFile(this);">' . Text::_('COM_RSFORM_REMOVE_FILE') . '</button> <input type="hidden" name="form[' . $data['NAME'] . '][]" value="' . RSFormProHelper::htmlEscape($file) . '" />' . RSFormProHelper::htmlEscape(basename($file)) . '</li>';
}
$multiple = !empty($data['MULTIPLE']) && $data['MULTIPLE'] == 'YES';
$new_field[1] .= '</ul>';
$new_field[1] .= '<input size="45" type="file" name="upload['.$name.']' . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' />';
break;
}
$return[] = $new_field;
}
$mainframe->triggerEvent('onRsformBackendGetEditFields', array(&$return, $submission));
return $return;
}
public function save()
{
$app = Factory::getApplication();
$db = $this->getDbo();
$formId = $app->input->getInt('formId');
$cid = $this->getSubmissionId();
$form = $app->input->post->get('form', array(), 'array');
$static = $app->input->post->get('formStatic', array(), 'array');
$files = $app->input->files->get('upload', array(), 'array');
$static['DateSubmitted'] = Factory::getDate($static['DateSubmitted'], Factory::getApplication()->get('offset'))->toSql();
if ($static['ConfirmedDate'])
{
$static['ConfirmedDate'] = Factory::getDate($static['ConfirmedDate'], Factory::getApplication()->get('offset'))->toSql();
}
else
{
$static['ConfirmedDate'] = null;
}
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/submissions.php';
$submission = RSFormProSubmissionsHelper::getSubmission($cid);
// Check if submission exists
if (!$submission)
{
return false;
}
// Handle file uploads first
if (!empty($files))
{
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/fields/fileupload.php';
foreach ($files as $field => $file)
{
if ($componentId = RSFormProHelper::getComponentId($field, $formId))
{
$data = RSFormProHelper::getComponentProperties($componentId);
// If we've cleared all files
if (!isset($form[$field]))
{
$form[$field] = array();
}
$valueSent = (array) $form[$field];
if (isset($submission->values[$field]))
{
$originals = RSFormProHelper::explode($submission->values[$field]);
foreach ($originals as $k => $original)
{
// File has been removed from list, remove the original file to save up space
if (!in_array($original, $valueSent) && file_exists($original) && is_file($original))
{
File::delete($original);
}
}
}
$f = new RSFormProFieldFileUpload(array(
'formId' => $formId,
'componentId' => $componentId,
'data' => $data,
));
if ($object = $f->processBeforeStore($submission->SubmissionId, $form, $files, false))
{
if (!is_array($form[$field]))
{
$form[$field] = (array) $form[$field];
}
if (!empty($data['MULTIPLE']) && $data['MULTIPLE'] === 'YES')
{
$form[$field] = array_merge($form[$field], RSFormProHelper::explode($object->FieldValue));
}
else
{
$form[$field] = RSFormProHelper::explode($object->FieldValue);
}
}
}
}
}
// Static submission data
if ($static)
{
$object = new stdClass();
$object->SubmissionId = $submission->SubmissionId;
foreach ($static as $field => $value)
{
$object->{$field} = $value;
}
$db->updateObject('#__rsform_submissions', $object, array('SubmissionId'), true);
}
// Checkboxes and other empty fields don't send a value, so just make sure we have them all here
if ($fields = $this->getEditFields())
{
foreach ($fields as $field)
{
if (!isset($form[$field[0]]))
{
$form[$field[0]] = '';
}
}
}
// Update dynamic fields
foreach ($form as $field => $value)
{
if (is_array($value))
{
$value = implode("\n", $value);
}
$object = (object) array(
'FormId' => $formId,
'SubmissionId' => $submission->SubmissionId,
'FieldName' => $field,
'FieldValue' => $value
);
if (!isset($submission->values[$field]))
{
$db->insertObject('#__rsform_submission_values', $object);
}
elseif ($submission->values[$field] !== $value)
{
// Update only if we've changed something
$db->updateObject('#__rsform_submission_values', $object, array('SubmissionId', 'FormId', 'FieldName'));
}
}
}
public function getSubmissionFormId()
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select($db->qn('FormId'))
->from($db->qn('#__rsform_submissions'))
->where($db->qn('SubmissionId') . ' = ' . $db->q($this->getSubmissionId()));
return $db->setQuery($query)->loadResult();
}
public function getExportSelected()
{
$cid = Factory::getApplication()->input->get('cid', array(), 'array');
$cid = array_map('intval', $cid);
return $cid;
}
public function getExportFile()
{
return uniqid('');
}
public function getStaticFields()
{
$submissionid = $this->getSubmissionId();
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__rsform_submissions'))
->where($db->qn('SubmissionId') . ' = ' . $db->q($submissionid));
$db->setQuery($query);
$submission = $db->loadObject();
if ($submission)
{
$submission->DateSubmitted = HTMLHelper::_('date', $submission->DateSubmitted, 'Y-m-d H:i:s');
if ($submission->ConfirmedDate)
{
$submission->ConfirmedDate = HTMLHelper::_('date', $submission->ConfirmedDate, 'Y-m-d H:i:s');
}
}
return $submission;
}
public function getExportType()
{
$task = Factory::getApplication()->input->getCmd('task');
$task = explode('.', $task);
return end($task);
}
public function getExportTotal()
{
$rows = Factory::getApplication()->input->get('ExportRows', '', 'string');
switch ($rows)
{
case '0':
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(' . $db->qn('SubmissionId') . ')')
->from($db->qn('#__rsform_submissions'))
->where($db->qn('FormId') . ' = ' . $db->q($this->getFormId()));
$db->setQuery($query);
return $db->loadResult();
break;
case '-1':
return $this->getTotal();
break;
default:
return count(explode(',', $rows));
break;
}
}
public function getImportTotal()
{
$app = Factory::getApplication();
$file = $app->get('tmp_path') . '/' . md5($app->get('secret'));
return file_exists($file) ? filesize($file) : 0;
}
public function getLanguages()
{
$languages = LanguageHelper::getKnownLanguages(JPATH_SITE);
$return = array();
$return[] = HTMLHelper::_('select.option', '', Text::_('RSFP_SUBMISSIONS_ALL_LANGUAGES'));
foreach ($languages as $tag => $properties)
{
$return[] = HTMLHelper::_('select.option', $tag, $properties['name']);
}
return $return;
}
public function getPreviewImportData()
{
$session = Factory::getSession();
$app = Factory::getApplication();
$file = $app->get('tmp_path') . '/' . md5($app->get('secret'));
$options = $session->get('com_rsform.import.options', array());
$skipHeaders = !empty($options['skipHeaders']);
$delimiter = empty($options['delimiter']) ? ',' : $options['delimiter'];
$enclosure = empty($options['enclosure']) ? '"' : $options['enclosure'];
$lines = array();
if (version_compare(PHP_VERSION, '8.1', '<'))
{
ini_set('auto_detect_line_endings', true);
}
setlocale(LC_ALL, 'en_US.UTF-8');
if (!file_exists($file))
{
$app->enqueueMessage(Text::sprintf('COM_RSFORM_IMPORT_NO_FILE_FOUND', $file), 'error');
return array();
}
$this->previewHeaders = array();
$h = fopen($file, 'r');
if (is_resource($h))
{
for ($i = 0; $i < 5; $i++)
{
$data = fgetcsv($h, 0, $delimiter, $enclosure);
if ($data !== false)
{
if ($i == 0)
{
$this->previewHeaders = $data;
if ($skipHeaders)
{
continue;
}
}
$lines[] = $data;
}
else
{
break;
}
}
fclose($h);
}
return $lines;
}
public function getPreviewSelectedData()
{
return $this->previewHeaders;
}
public function confirm($formId, $cid)
{
$db = Factory::getDbo();
$app = Factory::getApplication();
$form = RSFormProHelper::getForm($formId);
$ipAddress = $form->KeepIP ? IpHelper::getIp() : '0.0.0.0';
$query = $db->getQuery(true);
$query->select('*')
->from($db->qn('#__rsform_submissions'))
->where($db->qn('SubmissionId') . ' IN (' . implode(',', $db->q($cid)) . ')');
if ($submissions = $db->setQuery($query)->loadObjectList())
{
foreach ($submissions as $submission)
{
$SubmissionId = $submission->SubmissionId;
$hash = md5($submission->SubmissionId . $formId . $submission->DateSubmitted);
$query->clear()
->update($db->qn('#__rsform_submissions'))
->set($db->qn('confirmed') . ' = ' . $db->q(1))
->set($db->qn('ConfirmedDate') . ' = ' . $db->q(Factory::getDate()->toSql()))
->set($db->qn('ConfirmedIp') . ' = ' . $db->q($ipAddress))
->where($db->qn('SubmissionId') . ' = ' . $db->q($SubmissionId));
$db->setQuery($query);
$db->execute();
$app->triggerEvent('onRsformFrontendSubmissionConfirmation', array(array('SubmissionId' => $SubmissionId, 'hash' => $hash)));
if ($form->ConfirmSubmission && !empty($form->ConfirmSubmissionDefer) && json_decode($form->ConfirmSubmissionDefer))
{
RSFormProHelper::sendSubmissionEmails($SubmissionId);
}
}
}
}
public function saveColumns($formId, $staticcolumns, $columns)
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->delete($db->qn('#__rsform_submission_columns'))
->where($db->qn('FormId') . ' = ' . $db->q($formId));
$db->setQuery($query)->execute();
if ($staticcolumns || $columns)
{
$query->clear();
$query->insert($db->qn('#__rsform_submission_columns'))
->columns($db->qn(array('FormId', 'ColumnName', 'ColumnStatic')));
if ($staticcolumns)
{
foreach ($staticcolumns as $column)
{
$query->values(implode(',', array($db->q($formId), $db->q($column), $db->q(1))));
}
}
if ($columns)
{
foreach ($columns as $column)
{
$query->values(implode(',', array($db->q($formId), $db->q($column), $db->q(0))));
}
}
$db->setQuery($query)->execute();
}
}
}
class RSFormProSubmissionHeader
{
/* @var string Holds the actual value of the header */
public $value;
/* @var string Holds the label (displayed) value of the header */
public $label;
/* @var int 0 - form field, 1 - static submission header */
public $static;
/* @var int Checks if this header is shown in the submissions list */
public $enabled;
public function __construct($value, $label, $static = 0, $formId = 0)
{
$this->value = $value;
$this->label = $label;
$this->static = $static;
if ($formId)
{
$this->enabled = $this->isHeaderEnabled($formId);
}
}
public function __toString()
{
return $this->value;
}
protected function isHeaderEnabled($formId)
{
static $cache = array();
if (!isset($cache[$formId]))
{
$cache[$formId] = (object) array(
'staticHeaders' => array(),
'headers' => array()
);
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->qn('ColumnName'))
->select($db->qn('ColumnStatic'))
->from($db->qn('#__rsform_submission_columns'))
->where($db->qn('FormId') . ' = ' . $db->q($formId));
if ($results = $db->setQuery($query)->loadObjectList())
{
foreach ($results as $result)
{
if ($result->ColumnStatic)
{
$cache[$formId]->staticHeaders[] = $result->ColumnName;
}
else
{
$cache[$formId]->headers[] = $result->ColumnName;
}
}
}
}
$array = $this->static ? 'staticHeaders' : 'headers';
if (empty($cache[$formId]->headers) && empty($cache[$formId]->staticHeaders))
{
return true;
}
return in_array($this->value, $cache[$formId]->{$array});
}
}