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; } }