/** * Main method to get the data to insert into the form * * @return array Form's data */ public function getData() { // If already set return it. If not was causing issues with the juser form plugin // when it tried to modify the form->data info, from within its onLoad method, when sync user option turned on. if (isset($this->data)) { return $this->data; } $this->getRowId(); $input = $this->app->input; $profiler = JProfiler::getInstance('Application'); JDEBUG ? $profiler->mark('formmodel getData: start') : null; $this->data = array(); $f = JFilterInput::getInstance(); /* * $$$ hugh - we need to remove any elements from the query string, * if the user doesn't have access, otherwise ACL's on elements can * be bypassed by just setting value on form load query string! */ $clean_request = $f->clean($_REQUEST, 'array'); foreach ($clean_request as $key => $value) { $test_key = FabrikString::rtrimword($key, '_raw'); $elementModel = $this->getElement($test_key, false, false); if ($elementModel !== false) { if (!$elementModel->canUse()) { unset($clean_request[$key]); } } } $data = $clean_request; $form = $this->getForm(); $this->getGroupsHiarachy(); JDEBUG ? $profiler->mark('formmodel getData: groups loaded') : null; if (!$form->record_in_database) { FabrikHelperHTML::debug($data, 'form:getData from $_REQUEST'); $data = $f->clean($_REQUEST, 'array'); } else { JDEBUG ? $profiler->mark('formmodel getData: start get list model') : null; $listModel = $this->getListModel(); JDEBUG ? $profiler->mark('formmodel getData: end get list model') : null; $fabrikDb = $listModel->getDb(); JDEBUG ? $profiler->mark('formmodel getData: db created') : null; $listModel->getTable(); JDEBUG ? $profiler->mark('formmodel getData: table row loaded') : null; $this->aJoinObjs = $listModel->getJoins(); JDEBUG ? $profiler->mark('formmodel getData: joins loaded') : null; if ($this->hasErrors()) { // $$$ hugh - if we're a mambot, reload the form session state we saved in // process() when it banged out. if ($this->isMambot) { $sessionRow = $this->getSessionData(); $this->sessionModel->last_page = 0; if ($sessionRow->data != '') { $sData = unserialize($sessionRow->data); $data = FArrayHelper::toObject($sData, 'stdClass', false); JFilterOutput::objectHTMLSafe($data); $data = array($data); FabrikHelperHTML::debug($data, 'form:getData from session (form in Mambot and errors)'); } } else { // $$$ rob - use setFormData rather than $_GET // as it applies correct input filtering to data as defined in article manager parameters $data = $this->setFormData(); $data = FArrayHelper::toObject($data, 'stdClass', false); // $$$rob ensure "<tags>text</tags>" that are entered into plain text areas are shown correctly JFilterOutput::objectHTMLSafe($data); $data = ArrayHelper::fromObject($data); FabrikHelperHTML::debug($data, 'form:getData from POST (form not in Mambot and errors)'); } } else { $sessionLoaded = false; // Test if its a resumed paged form if ($this->saveMultiPage()) { $sessionRow = $this->getSessionData(); JDEBUG ? $profiler->mark('formmodel getData: session data loaded') : null; if ($sessionRow->data != '') { $sessionLoaded = true; /* * $$$ hugh - this chunk should probably go in setFormData, but don't want to risk any side effects just now * problem is that later failed validation, non-repeat join element data is not formatted as arrays, * but from this point on, code is expecting even non-repeat join data to be arrays. */ $tmp_data = unserialize($sessionRow->data); $groups = $this->getGroupsHiarachy(); foreach ($groups as $groupModel) { if ($groupModel->isJoin() && !$groupModel->canRepeat()) { foreach ($tmp_data['join'][$groupModel->getJoinId()] as &$el) { $el = array($el); } } } $bits = $data; $bits = array_merge($tmp_data, $bits); //$data = array(FArrayHelper::toObject($bits)); $data = $bits; FabrikHelperHTML::debug($data, 'form:getData from session (form not in Mambot and no errors'); } } if (!$sessionLoaded) { /* Only try and get the row data if its an active record * use !== '' as rowid may be alphanumeric. * Unlike 3.0 rowId does equal '' if using rowid=-1 and user not logged in */ $useKey = FabrikWorker::getMenuOrRequestVar('usekey', '', $this->isMambot); if (!empty($useKey) || $this->rowId !== '') { // $$$ hugh - once we have a few join elements, our select statements are // getting big enough to hit default select length max in MySQL. $listModel->setBigSelects(); // Otherwise lets get the table record /** * $$$ hugh - 11/14/2015 - ran into issue with the order by from a list being added to the form query, when * rendering a form with a content plugin in a list intro. And I don't think we ever need to * apply ordering to a form's select, by definition it's only one row. Leaving this here for * now just as a reminder in case there's any unforeseen side effects. * * $$$ hugh - 4/25/2016 - yes, there is an issue, as (duh!) ordering is needed for repeat groups. * Changing this back to original for now, will need to work out how to handle that corner case */ $opts = $input->get('task') == 'form.inlineedit' ? array('ignoreOrder' => true) : array(); // $opts = array('ignoreOrder' => true); $sql = $this->buildQuery($opts); $fabrikDb->setQuery($sql); FabrikHelperHTML::debug((string) $fabrikDb->getQuery(), 'form:render'); $rows = $fabrikDb->loadObjectList(); if (is_null($rows)) { JError::raiseWarning(500, $fabrikDb->getErrorMsg()); } JDEBUG ? $profiler->mark('formmodel getData: rows data loaded') : null; // $$$ rob Ack above didn't work for joined data where there would be n rows returned for "this rowid = $this->rowId \n"; if (!empty($rows)) { // Only do this if the query returned some rows (it wont if usekey on and userid = 0 for example) $data = array(); foreach ($rows as &$row) { if (empty($data)) { // If loading in a rowid=-1 set the row id to the actual row id $this->rowId = isset($row->__pk_val) ? $row->__pk_val : $this->rowId; } $row = empty($row) ? array() : ArrayHelper::fromObject($row); $request = $clean_request; $request = array_merge($row, $request); $data[] = FArrayHelper::toObject($request); } } FabrikHelperHTML::debug($data, 'form:getData from querying rowid= ' . $this->rowId . ' (form not in Mambot and no errors)'); // If empty data return and trying to edit a record then show error JDEBUG ? $profiler->mark('formmodel getData: empty test') : null; // Was empty($data) but that is never empty. Had issue where list prefilter meant record was not loaded, but no message shown in form if (empty($rows) && $this->rowId != '') { // $$$ hugh - special case when using -1, if user doesn't have a record yet if ($this->isUserRowId()) { return; } else { // If no key found set rowid to 0 so we can insert a new record. if (empty($useKey) && !$this->isMambot && in_array($input->get('view'), array('form', 'details'))) { $this->rowId = ''; /** * runtime exception is a little obtuse for people getting here from legitimate links, * like from an email, but aren't logged in so run afoul of a pre-filter, etc * So do the 3.0 thing, and raise a warning */ //throw new RuntimeException(FText::_('COM_FABRIK_COULD_NOT_FIND_RECORD_IN_DATABASE')); JError::raiseWarning(500, FText::_('COM_FABRIK_COULD_NOT_FIND_RECORD_IN_DATABASE')); } else { // If we are using usekey then there's a good possibility that the record // won't yet exist - so in this case suppress this error message $this->rowId = ''; } } } } } // No need to setJoinData if you are correcting a failed validation if (!empty($data)) { $this->setJoinData($data); } } } $this->data = $data; FabrikHelperHTML::debug($data, 'form:data'); JDEBUG ? $profiler->mark('queryselect: getData() end') : null; return $this->data; }
/** * main method to get the data to insert into the form * @return array form's data */ function getData() { //if already set return it. If not was causing issues with the juser form plugin // when it tried to modify the form->_data info, from within its onLoad method, when sync user option turned on. if (isset($this->_data)) { return $this->_data; } $profiler = JProfiler::getInstance('Application'); $this->_data = array(); $data = array(FArrayHelper::toObject(JRequest::get('request'))); $form = $this->getForm(); $aGroups = $this->getGroupsHiarachy(); JDEBUG ? $profiler->mark('formmodel getData: groups loaded') : null; if (!$form->record_in_database) { FabrikHelperHTML::debug($data, 'form:getData from $_REQUEST'); $data = JRequest::get('request'); } else { $listModel = $this->getListModel(); $fabrikDb = $listModel->getDb(); JDEBUG ? $profiler->mark('formmodel getData: db created') : null; $item = $listModel->getTable(); JDEBUG ? $profiler->mark('formmodel getData: table row loaded') : null; $this->_aJoinObjs =& $listModel->getJoins(); JDEBUG ? $profiler->mark('formmodel getData: joins loaded') : null; if (!empty($this->_arErrors)) { // $$$ hugh - if we're a mambot, reload the form session state we saved in // process() when it banged out. if ($this->isMambot) { $srow = $this->getSessionData(); $this->sessionModel->last_page = 0; if ($srow->data != '') { $data = FArrayHelper::toObject(unserialize($srow->data), 'stdClass', false); JFilterOutput::objectHTMLSafe($data); $data = array($data); FabrikHelperHTML::debug($data, 'form:getData from session (form in Mambot and errors)'); } } else { // $$$ rob - use setFormData rather than JRequest::get() //as it applies correct input filtering to data as defined in article manager parameters $data = $this->setFormData(); $data = FArrayHelper::toObject($data, 'stdClass', false); //$$$rob ensure "<tags>text</tags>" that are entered into plain text areas are shown correctly JFilterOutput::objectHTMLSafe($data); $data = array($data); FabrikHelperHTML::debug($data, 'form:getData from POST (form not in Mambot and errors)'); } } else { //test if its a resumed paged form $srow = $this->getSessionData(); JDEBUG ? $profiler->mark('formmodel getData: session data loaded') : null; if ($this->saveMultiPage() && $srow->data != '') { $data = array(FArrayHelper::toObject(array_merge(unserialize($srow->data), JArrayHelper::fromObject($data[0])))); FabrikHelperHTML::debug($data, 'form:getData from session (form not in Mambot and no errors'); } else { // only try and get the row data if its an active record //use !== 0 as rowid may be alphanumeric // $$$ hugh - when 'usekey', rowid can actually be 0 (like if using userid and this is guest access) // so go ahead and try and load the row, if it doesn't exist, we'll supress the warning $usekey = FabrikWorker::getMenuOrRequestVar('usekey', '', $this->isMambot); if (!empty($usekey) || (int) $this->_rowId !== 0 || !is_numeric($this->_rowId) && $this->_rowId != '') { // $$$ hugh - once we have a few join elements, our select statements are // getting big enough to hit default select length max in MySQL. $listModel->setBigSelects(); //otherwise lets get the table record $sql = $this->_buildQuery(); $fabrikDb->setQuery($sql); FabrikHelperHTML::debug($fabrikDb->getQuery(), 'form:render'); $rows = $fabrikDb->loadObjectList(); if (is_null($rows)) { JError::raiseWarning(500, $fabrikDb->getErrorMsg()); } JDEBUG ? $profiler->mark('formmodel getData: rows data loaded') : null; //$$$ rob Ack above didnt work for joined data where there would be n rows rerutned frho "this rowid = $this->_rowId \n"; if (!empty($rows)) { // only do this if the query returned some rows (it wont if usekey on and userid = 0 for example) $data = array(); foreach ($rows as &$row) { if (empty($data)) { //if loading in a rowid=-1 set the row id to the actual row id $this->_rowId = isset($row->__pk_val) ? $row->__pk_val : $this->_rowId; } $row = empty($row) ? array() : JArrayHelper::fromObject($row); $data[] = FArrayHelper::toObject(array_merge($row, JRequest::get('request'))); } } FabrikHelperHTML::debug($data, 'form:getData from querying rowid= ' . $this->_rowId . ' (form not in Mambot and no errors)'); // if empty data return and trying to edit a record then show error //occurs if user trying to edit a record forbidden by a prefilter rull if (empty($data) && $this->_rowId != '') { // $$$ hugh - special case when using -1, if user doesn't have a record yet if (FabrikWorker::getMenuOrRequestVar('rowid', '', $this->isMambot) == '-1') { return; } else { // if no key found set rowid to 0 so we can insert a new record. if (empty($usekey) && !$this->isMambot) { $this->_rowId = 0; JError::raiseNotice(500, JText::sprintf('COULD NOT FIND RECORD IN DATABASE', $this->_rowId)); return; } else { //if we are using usekey then theres a good possiblity that the record //won't yet exists- so in this case suppress this error message $this->_rowId = 0; } } } } } //no need to setJoinData if you are correcting a failed validation if (!empty($data)) { $this->setJoinData($data); } } //set the main part of the form's default data if ($this->_rowId != '') { $data = JArrayHelper::fromObject($data[0]); } else { //could be a view if ($listModel->isView()) { //@TODO test for new records from views $data = JArrayHelper::fromObject($data[0]); } else { if (($this->isMambot || $this->saveMultiPage()) && (!empty($data) && is_object($data[0]))) { $data = JArrayHelper::fromObject($data[0]); } else { // $$$ rob was causing notices when adding record with joined groups as $data[0]->join unset if we just use request //$data = JRequest::get('request'); $data = JArrayHelper::fromObject($data[0]); } } } $this->_listModel = $listModel; } //Test to allow {$my->id}'s to be evald from query strings $w = new FabrikWorker(); $data = $w->parseMessageForPlaceHolder($data); $this->_data = $data; FabrikHelperHTML::debug($data, 'form:data'); JDEBUG ? $profiler->mark('queryselect: getData() end') : null; return $this->_data; }
/** * Used to format the data when shown in the form's email * * @param mixed $value Element's data * @param array $data Form records data * @param int $repeatCounter Repeat group counter * * @return string Formatted value */ public function getEmailValue($value, $data = array(), $repeatCounter = 0) { $tmp = $this->_getOptions($data, $repeatCounter); // $$$ hugh - PLEASE LEAVE. No, we don't use $name, but I'm in here xdebug'ing stuff frequently, I use it as a time saver. $name = $this->getFullName(false, true); if ($this->isJoin()) { /** * $$$ hugh - if it's a repeat element, we need to render it as * a single entity * $$$ hugh - sometimes it's empty, not an array, so check just to * stop PHP whining about it. */ if (is_array($value)) { foreach ($value as &$v2) { foreach ($tmp as $v) { if ($v->value == $v2) { $v2 = $v->text; break; } } } } $oData = FArrayHelper::toObject($data); $val = $this->renderListData($value, $oData); } else { if (is_array($value)) { foreach ($value as &$v2) { foreach ($tmp as $v) { if ($v->value == $v2) { $v2 = $v->text; break; } } } $oData = FArrayHelper::toObject($data); $val = $this->renderListData($value, $oData); } else { foreach ($tmp as $v) { if ($v->value == $value) { $value = $v->text; break; } } $val = $this->renderListData($value, new stdClass()); } } if ($val === $this->_getSelectLabel()) { $val = ''; } return $val; }