shell bypass 403

Cubjrnet7 Shell


name : submissions.php
<?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&amp;task=submissions.viewfile&amp;id='.$result->SubmissionValueId.'&amp;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});
	}
}

© 2025 Cubjrnet7