6371, 'usmiles' => 3959);
protected $unSortable = array('signature');
protected $fieldOrder;
public function __construct($config = array(), MVCFactoryInterface $factory = null) {
if (!empty($config['formid'])) {
$id = $config['formid'];
}
else {
$id = Factory::getApplication()->input->getInt('id', -1);
}
$this->setId($id);
if (isset($config['context']) && $config['context'] != "") {
$this->context = $config['context'];
}
parent::__construct($config, $factory);
// create/ues a unique context which is used to distinguish mulitple adminForms on one page
$itemid = $this->getMenuId();
if (!empty($config['mid'])) {
$itemid = $config['mid'];
}
$this->paginationcontext = str_replace('.', '_', $this->context . '_' . $itemid . '_' . $id . '_');
if (isset($config['pparams']) && is_array($config['pparams'])) {
$this->pparams = $config['pparams'];
}
// get an array of fieldnames that can be used as search filter fields
// basically we could list all possible filter fields for the form but we keep it cleam
// which fields are actually used as filters is set in getFilterForm()
if (empty($config['filter_fields'])) {
$config['filter_fields'] = array();
}
if (isset($this->pparams) && is_array($this->pparams)) {
$params = new Registry;
$params->loadArray($this->pparams);
}
else {
$params = Factory::getApplication()->getParams();
}
$this->fieldOrder = $params->get('fieldorder', 'ordering');
$this->datafields = $this->getDatafields();
$fields = $this->datafields;
if (!empty($fields)) {
// add field id's to filter_fields
foreach ($fields as $field) {
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox', 'checkbox', 'selectsql', 'radiosql', 'multicheckboxsql')) && !empty($field->isfilterfield)) {
$config['filter_fields'][] = $this->paginationcontext . $field->name;
}
if ($field->typefield === 'location') {
$config['filter_fields'][] = $this->paginationcontext . $field->name;
$config['filter_fields'][] = $this->paginationcontext . $field->name . '_radius';
}
if ($field->typefield === 'date' && !empty($field->isfilterfield)) {
$config['filter_fields'][] = $this->paginationcontext . $field->name . '_min';
$config['filter_fields'][] = $this->paginationcontext . $field->name . '_max';
}
}
}
if ($canPublish = $this->canPublish()) {
$config['filter_fields'][] = $this->paginationcontext . 'published';
}
if ($params->get('show_filter_created')) {
$config['filter_fields'][] = $this->paginationcontext . 'mincreated';
$config['filter_fields'][] = $this->paginationcontext . 'maxcreated';
}
$this->visform = $this->getForm();
$this->displayedDefaultDbFields = $this->setDisplayedDefaultDbFields();
if (array_key_exists('ismfd', $this->displayedDefaultDbFields)) {
$config['filter_fields'][] = $this->paginationcontext . 'ismfd';
}
$this->pluginfieldlist = $this->setPluginFieldList();
if (isset($config['filter_fields'])) {
$this->filter_fields = $config['filter_fields'];
}
}
// must stay public
public function setId($id) {
// Set id and wipe data
$this->id = $id;
}
public function getId() {
return $this->id;
}
protected function populateState($ordering = null, $direction = null) {
// Initialise variables.
$app = Factory::getApplication();
$itemid = 0;
if (isset($this->pparams) && is_array($this->pparams)) {
$params = new Registry;
$params->loadArray($this->pparams);
}
else {
$params = $app->getParams();
if ($menu = $this->getMenuItem()) {
$itemid = ($menu->id) ? $menu->id : 0;
}
}
$this->setState('params', $params);
$this->setState('itemid', $itemid);
// Param count comes from plugin, if we have a list view with a limited fix amount of recordsets
$count = $params->get('count');
$limit = (isset($count) && is_numeric($count)) ? intval($count) : $params->get('display_num', 20);
$value = $app->input->get($this->paginationcontext . 'limit', $limit, 'uint');
$this->setState('list.limit', $value);
$value = $app->getUserStateFromRequest($this->paginationcontext . '.limitstart', $this->paginationcontext . 'limitstart', 0, 'uint');
$app->setUserState($this->paginationcontext . '.limitstart', $value);
$this->setState('list.start', $value);
// only filters of form that was sumitted are in request
$requestFilters = $app->input->get('filter', array(), 'array');
// stored filters of currently processed form
$sessionFilters = $app->getUserState($this->paginationcontext . '.filter', array());
$newFilters = array();
$filtersChanged = false;
// set filters of currently processed form according to stored session values and request values
// note: filters in session are stored as array, filters in model state are stored as objects with name filter.filtername
foreach ($requestFilters as $name => $value) {
if (strpos($name, $this->paginationcontext) !== false) {
$filtername = str_replace($this->paginationcontext, '', $name);
// Exclude if blacklisted
if (!in_array($name, $this->filterBlacklist)) {
$newFilters[$name] = $value;
$app->setUserState($this->paginationcontext . '.filter.' . $name, $value);
$this->setState('filter.' . $filtername, $value);
$filtersChanged = true;
}
}
}
if ($filtersChanged) {
$app->setUserState($this->paginationcontext . '.filter', $newFilters);
}
else {
foreach ($sessionFilters as $name => $value) {
// use stored filters as state filter
if (strpos($name, $this->paginationcontext) !== false) {
$filtername = str_replace($this->paginationcontext, '', $name);
$this->setState('filter.' . $filtername, $value);
}
}
}
// Out of the box, with Joomla! it is not possible to have more than one sortable table on a page (no prefix supported as for pagination), so one request can only handle one value for each parameter
// we add a unique context everywhere to distinguish between different adminForms and make sure that always the right filter_order and filter_order_dir control is filled in the admin form
$ordering = $app->getUserStateFromRequest($this->paginationcontext . '.ordering', $this->paginationcontext . 'filter_order', $this->getOrderingParamNameFromParams($params), 'string');
$this->setState('list.ordering', $ordering);
$direction = strtolower($app->getUserStateFromRequest($this->paginationcontext . '.direction', $this->paginationcontext . 'filter_order_Dir', $params->get('sortdirection', 'asc'), 'string'));
$this->setState('list.direction', $direction);
// filter.vfsortording is always submitted through the javascript that is used to order data on click on table header.
// Therefore we can set the state and user state directly from the $ordering and $direction, without checking the old sessionFilter values
$this->setState('filter.vfsortordering', $ordering . ' ' . $direction);
$app->setUserState($this->paginationcontext . '.filter.'.$this->paginationcontext.'vfsortordering', $ordering . ' ' . $direction);
}
protected function getOrderingParamNameFromParams($params) {
$test = $params->get('sortorder', 'id');
if (is_numeric($test)) {
return 'a.F'.$test;
}
if (strpos($test, 'a.') !== 0) {
return 'a.'.$test;
}
return $test;
}
public function getPagination() {
// Get a storage key.
$store = $this->getStoreId('getPagination');
// Try to load the data from internal storage.
if (isset($this->cache[$store])) {
return $this->cache[$store];
}
// Create the pagination object.
$limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links');
$page = new Pagination($this->getTotal(), $this->getStart(), $limit, $this->paginationcontext);
// Add the object to the internal cache.
$this->cache[$store] = $page;
return $this->cache[$store];
}
protected function getStoreId($id = '') {
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
return parent::getStoreId($id);
}
protected function getListQuery() {
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
$user = Factory::getApplication()->getIdentity();
$userId = $user->get('id');
$canDo = \VisformsHelper::getActions($this->id);
$canPublish = $this->canPublish();
$canPublishOwn= $this->canPublish('.own');
$fields = $this->datafields;
$menu_params = $this->getState('params', new Registry());
$layout = Factory::getApplication()->input->get('layout', 'data', 'string');
$isEditLayout = ($layout == "detailedit" || $layout == "dataeditlist") ? true : false;
$editableonly = ($isEditLayout) ? $menu_params->get('editableonly', 1) : $menu_params->get('editableonly', 0);
// Select the required fields from the table.
$query->select($this->getState('list.select', '*'));
$tn = "#__visforms_" . $this->id;
$query->from($db->quoteName($tn) . ' AS a');
if (!empty($canPublish) || !empty($canPublishOwn)) {
$searchfilter = $this->getState('filter.' . 'published');
// search filter is set
if ((isset($searchfilter)) && ($searchfilter != '') && in_array((int) $searchfilter, array(0,1))) {
// can only publish own; only display published records an unpublished own records according to filter settings
if (empty($canPublish) && $searchfilter == 0) {
$query->where($db->quoteName('published') . ' = ' . $searchfilter . ' AND ' . $db->quoteName('created_by') . " = " . $userId);
}
// searchfilter is set to published. Show all puslished recordsets
else {
$query->where($db->quoteName('published') . ' = ' . $searchfilter);
}
}
// no searchfilter set and user canPublishOwn
// Option "editable only" is stronger than can Publish. If it is enabled. Do not select by userid then
else if (empty($canPublish) && !($editableonly == 1)) {
$extraWhere = '';
if (!($editableonly == 1)) {
$extraWhere = ' OR (' . $db->quoteName('published') .' = ' . 0 . ' AND '. $db->quoteName('created_by') . ' = ' . $userId.')';
}
$query->where($db->quoteName('published') . ' = ' . 1 . $extraWhere);
}
else {
$query->where($db->quoteName('published') . ' IN (0,1)');
}
}
else {
$query->where($db->quoteName('published') . ' = ' . 1);
}
// only use the items specified in the fieldselect list
if (isset($this->pparams['fieldselect']) && is_array($this->pparams['fieldselect']) && (!empty($fields))) {
foreach ($this->pparams['fieldselect'] as $name => $value) {
if (is_numeric($name)) {
$name = "F" . $name;
}
$name = $db->escape($name);
$value = $db->escape($value);
foreach ($fields as $field) {
// different aproach for fields with multi select options
if ('F' . $field->id == $name) {
if (in_array($field->typefield, array('select', 'multicheckbox', 'selectsql', 'multicheckboxsql'))) {
$viewSelection = '%' .Visformsselect::$msdbseparator . $value . Visformsselect::$msdbseparator . '%';
$storedSelections = $query->concatenate(array($db->q(Visformsselect::$msdbseparator), $db->quoteName($name), $db->q(Visformsselect::$msdbseparator)));
$query->where('(' . $storedSelections . ' like ' . $db->q($viewSelection) . ')');
}
else {
$query->where($db->quoteName($name) . " = " . $db->quote($value), "AND");
}
}
}
}
}
if (!empty(\VisformsAEF::checkAEF(\VisformsAEF::$subscription))) {
if ($editableonly == 1) {
if ($canDo->get('core.edit.data')) {
// get all record sets
}
else if ($canDo->get('core.edit.own.data')) {
$query->where($db->quoteName('created_by') . " = " . $userId);
}
else {
// don't return any record sets, userid -1 does never exist
$query->where($db->quoteName('created_by') . " = -1 ");
}
}
}
if (!empty($this->visform->ownrecordsonly) && !($isEditLayout)) {
if (!empty($userId)) {
$query->where($db->quoteName('created_by') . " = " . $userId);
}
else {
// don't return any record sets
$query->where($db->quoteName('created_by') . " = -1 ");
}
}
// Filter by search
$filter = $this->getFilter();
if (!($filter === '')) {
$query->where($filter);
}
if (!empty($fields)) {
// apply select filter selctions
foreach ($fields as $field) {
// in plugin context use only fields which ar in the plugin field display list
if ((!empty($this->pparams)) && (!(in_array($field->id, $this->pluginfieldlist)))) {
continue;
}
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox', 'selectsql', 'radiosql', 'multicheckboxsql')) && !empty($field->isfilterfield)) {
$selectfilter = $this->getState('filter.' . $field->name);
// 0 is a valid option
if ((!isset($selectfilter)) || ($selectfilter === '')) {
continue;
}
$selectfilter = $db->escape($selectfilter);
// select recordsets
$viewSelection = '%' .Visformsselect::$msdbseparator . $selectfilter . Visformsselect::$msdbseparator . '%';
$storedSelections = $query->concatenate(array($db->q(Visformsselect::$msdbseparator), $db->quoteName('F' . $field->id), $db->q(Visformsselect::$msdbseparator)));
$query->where('(' . $storedSelections . ' like ' . $db->q($viewSelection) . ')');
continue;
}
// checkbox
if ($field->typefield == 'checkbox' && !empty($field->isfilterfield)) {
$selectfilter = $this->getState('filter.' . $field->name);
if ((!isset($selectfilter)) || ($selectfilter === '')) {
continue;
}
$selectfilter = $db->escape($selectfilter);
if ($selectfilter == 'checked') {
$query->where($db->quoteName('F'. $field->id) .' = ' . $db->q($field->attribute_value));
}
else {
$query->where('NOT' . $db->quoteName('F'. $field->id) .' = ' . $db->q($field->attribute_value));
}
}
// radius search
if ($field->typefield === "location" && !empty($field->allowferadiussearch)) {
$selectFilterLocation = $this->getState('filter.' . $field->name . '_location');
$selectFilterRadius = $this->getState('filter.' . $field->name . '_radius');
// empty radius means everywhere
if (empty($selectFilterRadius) || !isset($selectFilterLocation['lat']) || $selectFilterLocation['lat'] === "" || !isset($selectFilterLocation['lng']) || $selectFilterLocation['lng'] === "") {
continue;
}
$selectFilterLocation = $db->escape($selectFilterLocation);
$selectFilterLocation = HTMLHelper::_('visformslocation.extractDbValue', $selectFilterLocation);
$selectFilterRadius = $db->escape($selectFilterRadius);
$earthRadius = (!empty($field->distanceunit) && isset($this->radius[$field->distanceunit])) ? $this->radius[$field->distanceunit] : $this->radius['km'];
$query->where("SUBSTRING(SUBSTRING_INDEX(F" . $field->id . ", ',', 1),9, (LENGTH(SUBSTRING_INDEX(F" . $field->id . ", ',', 1))-9)) != '' ");
$query->where("SUBSTRING(SUBSTRING_INDEX(F" . $field->id . ", ',', -1),8, (LENGTH(SUBSTRING_INDEX(F" . $field->id . ", ',', 1))-9)) != '' ");
$query->where($earthRadius . " * acos( cos( radians(" . $selectFilterLocation['lat'] . "*1) ) * cos( radians( (SUBSTRING(SUBSTRING_INDEX(F" . $field->id . ", ',', 1),9, (LENGTH(SUBSTRING_INDEX(F" . $field->id . ", ',', 1))-9))) *1 ) ) * cos( radians(" . $selectFilterLocation['lng'] . "*1 ) - radians((SUBSTRING(SUBSTRING_INDEX(F" . $field->id . ", ',', -1),8, (LENGTH(SUBSTRING_INDEX(F" . $field->id . ", ',', 1))-9)))*1) ) + sin( radians(" . $selectFilterLocation['lat'] . "*1) ) * sin( radians( (SUBSTRING(SUBSTRING_INDEX(F" . $field->id . ", ',', 1),9, (LENGTH(SUBSTRING_INDEX(F" . $field->id . ", ',', 1))-9)))*1 ) ) ) < " . $selectFilterRadius);
}
if ($field->typefield === "date" && !empty($field->isfilterfield)) {
$formats = explode(';', $field->format);
$format = $formats[1];
$searchfilter = $this->getState('filter.' . $field->name . '_min');
if ((isset($searchfilter)) && ($searchfilter != '') && !empty($searchfilter)) {
$searchfilter = $db->escape($searchfilter);
$query->where(' STR_TO_DATE(' . $db->quoteName('F'. $field->id) . ', ' . $db->quote($format) . ') > STR_TO_DATE(' . $db->q($searchfilter) . ', ' . $db->quote($format) . ')');
}
$searchfilter = $this->getState('filter.' . $field->name . '_max');
if ((isset($searchfilter)) && ($searchfilter != '') && !empty($searchfilter)) {
$searchfilter = $db->escape($searchfilter);
$query->where(' STR_TO_DATE(' . $db->quoteName('F'. $field->id) . ', ' . $db->quote($format) . ') < STR_TO_DATE(' . $db->q($searchfilter) . ', ' . $db->quote($format) . ')');
}
}
}
}
// foreach ($this->displayedDefaultDbFields as $fieldname => $name)
if ((!empty($this->displayedDefaultDbFields)) && isset($this->displayedDefaultDbFields['ismfd'])) {
$searchfilter = $db->escape($this->getState('filter.' . 'ismfd'));
if ((isset($searchfilter)) && ($searchfilter != '')) {
$searchfilter = $db->escape($searchfilter);
$query->where($db->quoteName('ismfd') . ' = ' . $searchfilter);
}
}
$searchfilter = $db->escape($this->getState('filter.' . 'mincreated'));
if ((isset($searchfilter)) && ($searchfilter != '') && $searchfilter != $db->getNullDate()) {
$searchfilter = $db->escape($searchfilter);
$searchfilter = Factory::getDate($searchfilter)->toSql();
$query->where($db->quoteName('created') . ' > ' . $db->q($searchfilter));
}
$searchfilter = $this->getState('filter.' . 'maxcreated');
if ((isset($searchfilter)) && ($searchfilter != '') && $searchfilter != $db->getNullDate()) {
$searchfilter = $db->escape($searchfilter);
$searchfilter = Factory::getDate($searchfilter)->toSql();
$query->where($db->quoteName('created') . ' < ' . $db->q($searchfilter));
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'id');
if (is_numeric($orderCol)) {
$orderCol = "F" . $orderCol;
}
$orderCol = $db->escape($orderCol);
$this->setState('list.ordering', $orderCol);
$orderDirn = $this->state->get('list.direction', 'asc');
// we store dates as strings in database. If sort order field is of type date we have to convert the strings before we order the recordsets
if (!empty($fields)) {
foreach ($fields as $field) {
$fname = 'F' . $field->id;
if (($field->typefield == 'date') && (($orderCol == $fname) || ($orderCol == 'a.' . $fname))) {
$formats = explode(';', $field->format);
$format = $formats[1];
$orderCol = ' STR_TO_DATE(' . $orderCol . ', ' . $db->quote($format) . ') ';
break;
}
if ((($field->typefield == 'number') || ($field->typefield == 'calculation')) && (($orderCol == $fname) || ($orderCol == 'a.' . $fname))) {
$orderCol = '(' . $orderCol . ' * 1)';
}
}
}
$query->order($orderCol . ' ' . $db->escape($orderDirn));
return $query;
}
public function getDatafields() {
// Lets load the data if it doesn't already exist
// exclude all fieldtypes that should not be published in frontend (submits, resets, fieldseparator)
$datafields = $this->datafields;
if (empty($datafields)) {
$fieldorder = (!empty($this->fieldOrder)) ? $this->fieldOrder : 'ordering';
$db = Factory::getDbO();
$user = Factory::getApplication()->getIdentity();
$groups = $user->getAuthorisedViewLevels();
$frontaccess = implode(", ", $groups);
$excludedFieldTypes = "'reset', 'submit', 'image', 'fieldsep'";
$query = $db->getQuery(true);
$query->select('*')
->from($db->quoteName('#__visfields'))
->where($db->quoteName('fid') . " = " . $this->id)
->where($db->quoteName('published') . ' = ' . 1)
->where($db->quoteName('frontaccess') . " in (" . $frontaccess . ")")
->where($db->quoteName('typefield') . "not in (" . $excludedFieldTypes . ")")
->where('(' . $db->qn('frontdisplay') . ' is null or ' . $db->qn('frontdisplay') . ' in (1,2,3))')
->order($db->quoteName($fieldorder) . " asc");
try {
$db->setQuery($query);
$datafields = $db->loadObjectList();
}
catch (\Exception $ex) {
}
$n = count($datafields);
for ($i = 0; $i < $n; $i++) {
$datafields[$i]->defaultvalue = \VisformsHelper::registryArrayFromString($datafields[$i]->defaultvalue);
foreach ($datafields[$i]->defaultvalue as $name => $value) {
// make names shorter and set all defaultvalues as properties of field object
$prefix = 'f_' . $datafields[$i]->typefield . '_';
if (strpos($name, $prefix) !== false) {
$key = str_replace($prefix, "", $name);
$datafields[$i]->$key = $value;
}
}
// delete defaultvalue array
unset($datafields[$i]->defaultvalue);
if (in_array($datafields[$i]->typefield, $this->unSortable)){
$datafields[$i]->unSortable = true;
}
else {
$datafields[$i]->unSortable = false;
}
}
$this->datafields = $datafields;
}
return $datafields;
}
public function getDetail() {
$db = Factory::getDbO();
$app = Factory::getApplication();
$cIds = $app->input->get('cid', array(), 'ARRAY');
ArrayHelper::toInteger($cIds);
$menu_params = $this->getState('params', new Registry());
$layout = $app->input->get('layout', 'data', 'string');
$isEditLayout = ($layout == "detailedit" || $layout == "dataeditlist") ? true : false;
$editableonly = ($isEditLayout) ? $menu_params->get('editableonly', 1) : $menu_params->get('editableonly', 0);
$task = $app->input->get('task');
$isPdfTask = ($task === 'renderPdf' || $task === 'renderPdfList');
$canPublish = $this->canPublish();
$canPublishOwn = $this->canPublish('.own');
$canDo = \VisformsHelper::getActions($this->id);
$id = (int) $cIds[0];
$user = Factory::getApplication()->getIdentity();
$userId = $user->get('id');
$query = $db->getQuery(true);
$query->select('*')
->from($db->quoteName('#__visforms_' . $this->id))
->where($db->quoteName('id') . " = " . $id);
// if a user can publish/unpublish a recordset, unpublished recordsets are displayed in the list view and the user can display a details view of the unpublished record as well
if (empty($canPublish) && empty($canPublishOwn)) {
$query->where($db->quoteName('published') . ' = ' . 1);
}
else if (empty($canPublish)) {
$query->where($db->quoteName('published') . ' = '. 1 . ' OR (' . $db->quoteName('published') .' = '. 0 .' AND '. $db->quoteName('created_by') . ' = ' . $userId.')');
}
else {
$query->where($db->quoteName('published') . ' IN (0,1)');
}
if (!empty(\VisformsAEF::checkAEF(\VisformsAEF::$subscription))) {
if ($editableonly == 1) {
if ($canDo->get('core.edit.data')) {
// get all record sets
} else if ($canDo->get('core.edit.own.data')) {
$query->where($db->quoteName('created_by') . " = " . $userId);
} else {
// don't return any record sets
$query->where($db->quoteName('created_by') . " = -1 ");
}
}
}
// when getting data for pdf in data views $isEditLayout is always true and this code section is ignored
if (!empty($this->visform->ownrecordsonly) && !($isEditLayout)) {
if (!empty($userId)) {
$query->where($db->quoteName('created_by') . " = " . $userId);
} else {
// don't return any record sets
$query->where($db->quoteName('created_by') . " = -1 ");
}
}
try {
$db->setQuery($query);
$detail = $db->loadObject();
}
catch (\Exception $ex) {
return false;
}
// for fields of type select, radio, multicheckbox and checkbox display option label in data view instead of the stored option values
// do not replace values in data, if data are used to create a pdf $isPdfTask
// in pdfTasks, placeholder replacement will output the correct value
if (!empty($detail) && !$isPdfTask) {
$fields = $this->datafields;
foreach ($fields as $field) {
$detailfieldname = "F" . $field->id;
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox'))) {
$detailfieldvalue = $detail->$detailfieldname;
if ((!isset($detailfieldvalue)) || ($detailfieldvalue === '') || (empty($field->list_hidden))) {
continue;
}
$newextracteditemfieldvalues = HTMLHelper::_('visformsselect.mapDbValueToOptionLabel', $detailfieldvalue, $field->list_hidden);
$newitemfieldvalue = implode('
', $newextracteditemfieldvalues);
$detail->$detailfieldname = $newitemfieldvalue;
}
if (in_array($field->typefield, array('selectsql', 'radiosql', 'multicheckboxsql'))) {
$detailfieldvalue = $detail->$detailfieldname;
if ((!isset($detailfieldvalue)) || ($detailfieldvalue === '')) {
continue;
}
$newextracteditemfieldvalues = HTMLHelper::_('visformsselect.mapDbValueToSqlOptionLabel', $detailfieldvalue, $field->sql);
$newitemfieldvalue = implode('
', $newextracteditemfieldvalues);
$detail->$detailfieldname = $newitemfieldvalue;
}
if ($field->typefield == 'location') {
$detail->$detailfieldname = \VisformsHelper::registryArrayFromString($detail->$detailfieldname);
if (!empty($field->displayAsMapInDetail)) {
$detail->requiresJs = true;
}
}
}
}
return $detail;
}
public function getForm() {
$form = $this->visform;
$hassub = \VisformsAEF::checkAEF(\VisformsAEF::$subscription);
if (empty($form)) {
$db = Factory::getDbO();
$query = $db->getQuery(true);
$query->select('*')
->from($db->quoteName('#__visforms'))
->where($db->quoteName('id') . " = " . $this->id)
->where($db->quoteName('published') . ' = ' . 1)
->where($db->quoteName('saveresult') . ' = ' . 1);
$db->setQuery($query);
$form = $db->loadObject();
if (empty($form)) {
return $form;
}
// Convert frontendsettings field to an array
$form->frontendsettings = \VisformsHelper::registryArrayFromString($form->frontendsettings);
foreach ($form->frontendsettings as $name => $value) {
if (($name == 'ownrecordsonly') && (empty($hassub))) {
$value = 0;
}
if (($name == 'displaycounter') && (empty($hassub))) {
$value = 0;
}
// make names shorter and set all frontendsettings as properties of form object
$form->$name = $value;
}
$form->mapCounter = 0;
$form->hasLocationRadiusSearch = false;
$form = $this->cleanForm($form);
}
return $form;
}
protected function cleanForm($form) {
if (!isset($form->displaydetail)) {
$form->displaydetail = 0;
}
if (!isset($form->hideemptyfieldsindetail)) {
$form->hideemptyfieldsindetail = 0;
}
// each data view has to check, whether do display the overheadfiels or not. Use only one boolean option, and make sure it is set.
$displayParameters = array ('displayip', 'displayid', 'displaycreated', 'displaycreatedtime', 'displayismfd', 'displaymodifiedat', 'displaymodifiedattime', 'displaypdfexportbutton');
foreach ($displayParameters as $parameter) {
if (!isset($form->$parameter)) {
$form->$parameter = 0;
}
// display in list view
$listParamName = $parameter . '_list';
$form->$listParamName = ($form->$parameter == "1" || $form->$parameter == "2") ? true : false;
// display in detail vies
$detailParamName = $parameter . '_detail';
$form->$detailParamName = ($form->$parameter == "1" || $form->$parameter == "3") ? true : false;
// display in any view of content plugin data view
$plgParamName = $parameter . '_plg';
$form->$plgParamName = (!empty($this->pparams) && $this->pparams[$parameter] == "true" && ($form->$parameter == "1" || $form->$parameter == "2" || $form->$parameter == "3")) ? true : false;
}
return $form;
}
private function getMenuItem() {
$app = Factory::getApplication();
$menu = $app->getMenu()->getActive();
$lang = $app->getLanguage();
if (!$menu) {
$menu = $app->getMenu()->getDefault($lang->getTag());
}
return $menu;
}
public function getFilterForm($data = array(), $loadData = true) {
$menuParams = $this->state->get('params');
// we need to add the path explicitely for use with plugin dataview
FormHelper::addFieldPath("Visolutions\Component\Visforms\Site\Field");
FormHelper::addFormPath(JPATH_ROOT ."/components/com_visforms/forms");
$form = parent::getFilterForm($data, false);
if (!empty($form)) {
$fields = $this->datafields;
$searchfieldxml = new \SimpleXMLElement('');
$form->setField($searchfieldxml, 'filter');
$form->setFieldAttribute('search', 'name', $this->paginationcontext . 'search', 'filter');
$showCreatedFilter = $menuParams->get('show_filter_created', false);
if ($showCreatedFilter === "true" || $showCreatedFilter == 1) {
$dateformat = Text::_('DATE_FORMAT_LC4');
$mySqlDateFormat = str_replace('d', '%d', str_replace('m', '%m', str_replace('Y', '%Y', $dateformat)));
$minCreatedfieldxml = new \SimpleXMLElement('
');
$form->setField($minCreatedfieldxml, 'filter');
$form->setFieldAttribute('mincreated', 'name', $this->paginationcontext . 'mincreated', 'filter');
$maxCreatedfieldxml = new \SimpleXMLElement('
');
$form->setField($maxCreatedfieldxml, 'filter');
$form->setFieldAttribute('maxcreated', 'name', $this->paginationcontext . 'maxcreated', 'filter');
}
if (array_key_exists('ismfd', $this->displayedDefaultDbFields)) {
$ismfdfieldxml = new \SimpleXMLElement('
');
$form->setField($ismfdfieldxml, 'filter');
$form->setFieldAttribute('ismfd', 'name', $this->paginationcontext . 'ismfd', 'filter');
}
$canPublish = $this->canPublish() || $this->canPublish('.own');
if (!empty($canPublish)) {
$publishedfieldxml = new \SimpleXMLElement('
');
$form->setField($publishedfieldxml, 'filter');
$form->setFieldAttribute('published', 'name', $this->paginationcontext . 'published', 'filter');
}
$xml =
'
';
if (!empty($canPublish)) {
$xml .= '
';
}
if (array_key_exists('created', $this->displayedDefaultDbFields)) {
$xml .= '
';
}
if (array_key_exists('ipaddress', $this->displayedDefaultDbFields)) {
$xml .= '
';
}
if (array_key_exists('ismfd', $this->displayedDefaultDbFields)) {
$xml .= '
';
}
if (array_key_exists('modified', $this->displayedDefaultDbFields)) {
$xml .= '
';
}
foreach ($fields as $field) {
if ((!empty($this->pparams))) {
if (!(in_array($field->id, $this->pluginfieldlist))) {
continue;
}
} // only search filter for fields which are displayed in list view
else if ((!empty($field->frontdisplay))) {
if ($field->frontdisplay == 3) {
continue;
}
}
if (empty($field->unSortable)) {
$xml .= '';
$xml .= '';
}
}
$xml .= '';
$sortorderfieldxml = new \SimpleXMLElement($xml);
$form->setField($sortorderfieldxml, 'filter');
$form->setFieldAttribute('vfsortordering', 'name', $this->paginationcontext . 'vfsortordering', 'filter');
// if we come from the dataview plugin, only show filter of fields which are in the plugins fieldlist
foreach ($fields as $field) {
if ((!empty($this->pparams))) {
if (!(in_array($field->id, $this->pluginfieldlist))) {
continue;
}
} // only search filter for fields which are displayed in list view
else if ((!empty($field->frontdisplay))) {
if ($field->frontdisplay == 3) {
continue;
}
}
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox', 'selectsql', 'radiosql', 'multicheckboxsql')) && $field->isfilterfield) {
if ($this->getListBoxFilterField($field) !== false) {
$addFilterField = new \SimpleXMLElement($this->getListBoxFilterField($field));
$form->setField($addFilterField, 'filter');
}
}
if ($field->typefield == 'checkbox' && $field->isfilterfield) {
if ($this->getCheckboxFilterField($field) !== false) {
$addFilterField = new \SimpleXMLElement($this->getCheckboxFilterField($field));
$form->setField($addFilterField, 'filter');
}
}
if ($field->typefield === "location" && !empty($field->allowferadiussearch)) {
$this->visform->hasLocationRadiusSearch = true;
$locationSearchXml = '';
$addFilterField = new \SimpleXMLElement($locationSearchXml);
$form->setField($addFilterField, 'filter');
$locationLocationXml = '';
$addFilterField = new \SimpleXMLElement($locationLocationXml);
$form->setField($addFilterField, 'filter');
$distanceUnit = (!empty($field->distanceunit)) ? $field->distanceunit : 'km';
$label = Text::sprintf('COM_VISFORMS_FILTER_SELECT_LABEL', Text::sprintf('COM_VISFORMS_RADIUS', $distanceUnit));
$options = '';
foreach (array(10, 20, 50, 100, 1000) as $fieldoption) {
$options .= '';
}
$locationRadiusXml = '' . $options . '
';
$addFilterField = new \SimpleXMLElement($locationRadiusXml);
$form->setField($addFilterField, 'filter');
}
if ($field->typefield === "date" && !empty($field->isfilterfield)) {
$formats = explode(';', $field->format);
$dateFieldSearchXml = '
';
$addFilterField = new \SimpleXMLElement($dateFieldSearchXml);
$form->setField($addFilterField, 'filter');
$form->setFieldAttribute($this->paginationcontext . $field->name . '_min', 'label', $field->label . ' ' . Text::_('COM_VISFORMS_FILTER_DATE_AFTER'), 'filter');
$form->setFieldAttribute($this->paginationcontext . $field->name . '_min', 'hint', $field->label . ' ' . Text::_('COM_VISFORMS_FILTER_DATE_AFTER'), 'filter');
$dateFieldSearchXml = '
';
$addFilterField = new \SimpleXMLElement($dateFieldSearchXml);
$form->setField($addFilterField, 'filter');
$form->setFieldAttribute($this->paginationcontext . $field->name . '_max', 'label', $field->label . ' ' . Text::_('COM_VISFORMS_FILTER_DATE_BEFORE'), 'filter');
$form->setFieldAttribute($this->paginationcontext . $field->name . '_max', 'hint', $field->label . ' ' . Text::_('COM_VISFORMS_FILTER_DATE_BEFORE'), 'filter');
}
}
}
$data = $this->loadFormData();
$form->bind($data);
return $form;
}
public function getActiveFilters() {
$activeFilters = array();
if (!empty($this->filter_fields)) {
foreach ($this->filter_fields as $filter) {
$contextfreefiltername = str_replace($this->paginationcontext, '', $filter);
$filterName = 'filter.' . $contextfreefiltername;
if (!empty($this->state->get($filterName)) || is_numeric($this->state->get($filterName))) { // J5 ListModel
// if (property_exists($this->state, $filterName) && (!empty($this->state->{$filterName}) || is_numeric($this->state->{$filterName}))) { // J4 ListModel
$activeFilters[$filter] = $this->state->get($filterName);
}
}
}
return $activeFilters;
}
protected function loadFormData() {
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState($this->paginationcontext, new \stdClass);
// Pre-fill the list options
if (!property_exists($data, 'list')) {
/* $data->list = array(
'direction' => $this->state->{'list.direction'},
'limit' => $this->state->{'list.limit'},
'ordering' => $this->state->{'list.ordering'},
'start' => $this->state->{'list.start'}
); */ // J4
$data->list = [
'direction' => $this->getState('list.direction'),
'limit' => $this->getState('list.limit'),
'ordering' => $this->getState('list.ordering'),
'start' => $this->getState('list.start'),
]; // J5
}
return $data;
}
protected function getFilter() {
// Get Filter parameters
$fields = $this->datafields;
$searchfilter = $this->getState('filter.search');
$filter = '';
if (($searchfilter != '') && (!empty($fields))) {
$referenceDate = Factory::getDate('now', 'UTC');
$userTimeZone = new \DateTimeZone(Factory::getConfig()->get('offset'));
$offsetInSeconds = $userTimeZone->getOffset($referenceDate);
$sign =($offsetInSeconds < 0) ? '-' : '+';
$offsetInSeconds = abs($offsetInSeconds);
$filter .= " (";
foreach ($fields as $field) {
if ((!empty($this->pparams)) && (!(in_array($field->id, $this->pluginfieldlist)))) {
continue;
}
if ($field->typefield == 'signature') {
continue;
}
// string search in all fields which are not displayed as filter
if (empty($field->isfilterfield)) {
$prop = "F" . $field->id;
$filter .= " upper(" . $prop . ") like upper('%" . $searchfilter . "%') or ";
}
}
foreach ($this->displayedDefaultDbFields as $fieldname => $name) {
$dateformat = Text::_('DATE_FORMAT_LC4');
$mySqlDateFormat = str_replace('d', '%d', str_replace('m', '%m', str_replace('Y', '%Y', $dateformat)));
if ((($fieldname == 'created') && ($name == 'displaycreated')) || (($fieldname == 'modified') && ($name == 'displaymodifiedat'))) {
$filter .= " from_unixtime((unix_timestamp(".$fieldname.") ".$sign." ".$offsetInSeconds ."), '".$mySqlDateFormat."') like '%".$searchfilter."%' or ";
}
else if ((($fieldname == 'created') && ($name == 'displaycreatedtime')) || (($fieldname == 'modified') && ($name == 'displaymodifiedattime'))) {
$filter .= " from_unixtime((unix_timestamp(".$fieldname.") ".$sign." ".$offsetInSeconds ."), '".$mySqlDateFormat." %H:%i:%s') like '%".$searchfilter."%' or ";
}
else if ($fieldname != 'ismfd') {
$filter .= " " . $fieldname . " like '%" . $searchfilter . "%' or ";
}
}
$filter = rtrim($filter, 'or ');
$filter = $filter . " )";
}
return $filter;
}
public function getContext() {
if (!empty($this->paginationcontext)) {
return $this->paginationcontext;
}
return '';
}
protected function getListBoxFilterField($field) {
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox')) && empty($field->list_hidden)) {
return false;
}
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox'))) {
$fieldoptions = HTMLHelper::_('visformsselect.extractHiddenList', $field->list_hidden);
}
else {
// selectsql, radiosql, multicheckboxsql
// try to get options directly from sql statement
$fieldoptions = HTMLHelper::_('visformsselect.getOptionsFromSQL', $field->sql);
if (count($fieldoptions) === 0) {
// sql statement with user or input placeholder does not return proper filter field option list
// Use stored form data as source for filter options
$fieldoptions = HTMLHelper::_('visformsselect.getOptionListForSQLFilterFields', $field->id, $field->fid, $this->canPublish());
}
}
$label = Text::sprintf('COM_VISFORMS_FILTER_SELECT_LABEL', htmlspecialchars($field->label, ENT_COMPAT, 'UTF-8'));
$options = '';
if (!empty($fieldoptions)) {
foreach ($fieldoptions as $fieldoption) {
$options .= '';
}
}
$xmlstring = '' . $options . '
';
return $xmlstring;
}
protected function getCheckboxFilterField($field) {
if ($field->typefield = 'checkbox' && !isset($field->attribute_value)) {
return false;
}
$label = Text::sprintf('COM_VISFORMS_FILTER_SELECT_LABEL', htmlspecialchars($field->label, ENT_COMPAT, 'UTF-8'));
$options = '';
$options .= '';
$options .= '';
$xmlstring = '' . $options . '
';
return $xmlstring;
}
public function getRawItems() {
return parent::getItems();
}
public function getItems() {
$items = parent::getItems();
$fields = $this->datafields;
if ((empty($items)) || empty($fields)) {
return $items;
}
$n = count($items);
for ($i = 0; $i < $n; $i++) {
foreach ($fields as $field) {
$itemfieldname = "F" . $field->id;
// display options labels for selects, radios, multicheckboxes and checkboxes in frontend data views not the stored option values
if (in_array($field->typefield, array('select', 'radio', 'multicheckbox'))) {
$itemfieldvalue = $items[$i]->$itemfieldname;
if ((!isset($itemfieldvalue)) || ($itemfieldvalue === '') || (empty($field->list_hidden))) {
continue;
}
$newextracteditemfieldvalues = HTMLHelper::_('visformsselect.mapDbValueToOptionLabel', $itemfieldvalue, $field->list_hidden);
$newitemfieldvalue = implode('
', $newextracteditemfieldvalues);
$items[$i]->$itemfieldname = $newitemfieldvalue;
}
if (in_array($field->typefield, array('selectsql', 'radiosql', 'multicheckboxsql'))) {
$itemfieldvalue = $items[$i]->$itemfieldname;
if ((!isset($itemfieldvalue)) || ($itemfieldvalue === '')) {
continue;
}
$newextracteditemfieldvalues = HTMLHelper::_('visformsselect.mapDbValueToSqlOptionLabel', $itemfieldvalue, $field->sql);
$newitemfieldvalue = implode('
', $newextracteditemfieldvalues);
$items[$i]->$itemfieldname = $newitemfieldvalue;
}
if ($field->typefield == 'location') {
$items[$i]->$itemfieldname = \VisformsHelper::registryArrayFromString($items[$i]->$itemfieldname);
}
}
}
return $items;
}
// only use in list views!
protected function setDisplayedDefaultDbFields() {
$displayedDefaultDbFields = $this->displayedDefaultDbFields;
if (empty($displayedDefaultDbFields)) {
$form = $this->visform;
$displayedDefaultDbFields = array();
$formParamNames = array('displayip' => 'ipaddress', 'displaycreated' => 'created', 'displaycreatedtime' => 'created', 'displayismfd' => 'ismfd', 'displaymodifiedat' => 'modified', 'displaymodifiedattime' => 'modified');
foreach ($formParamNames as $name => $fieldname) {
if ((isset($form->$name)) && (in_array($form->$name, array('1', '2')))) {
if ((empty($this->pparams)) || ((isset($this->pparams[$name])) && ($this->pparams[$name] === 'true'))) {
// use named array, in order to prevent two elements with value created
$displayedDefaultDbFields[$fieldname] = $name;
}
}
}
}
return $displayedDefaultDbFields;
}
protected function canPublish($own = '') {
$permission = 'core.edit'.$own.'.data.state';
$canDo = \VisformsHelper::getActions($this->id);
$layout = Factory::getApplication()->input->get('layout', 'data', 'string');
if ((!empty(\VisformsAEF::checkAEF(\VisformsAEF::$subscription))) && ($canDo->get($permission))
&& (($layout == 'detailedit') || ($layout == 'dataeditlist'))) {
return true;
}
return false;
}
// only use in list views!
protected function setPluginFieldList() {
$pluginfieldlist = array();
if ((!empty($this->pparams)) && (!empty($this->pparams['fieldlist']))) {
$rawpluginfieldlist = explode(',', $this->pparams['fieldlist']);
$fields = $this->datafields;
foreach ($rawpluginfieldlist as $value) {
$fieldid = trim($value);
foreach ($fields as $field) {
// if any sort of frontdisplay is enable for the field in field configuration, it is displayed by the plugin vfdataview
if (($field->id == $fieldid) && (in_array($field->frontdisplay, array('1', '2', '3')))) {
$pluginfieldlist[] = $fieldid;
}
}
}
}
return $pluginfieldlist;
}
// deprecated, use JHTMLVisforms::checkDataViewMenuItemExists
// keep for compatibility with older subscription versions.
public function checkDataViewMenuItemExists() {
return HTMLHelper::_('visforms.checkDataViewMenuItemExists', $this->id);
}
public function getMenuId() {
if ($menu = $this->getMenuItem()) {
return ($menu->id) ? $menu->id : 0;
}
return 0;
}
}