Exemple #1
0
 /**
  * Process the form to the database
  *
  * @return string Insert id
  */
 public function processToDB()
 {
     $profiler = JProfiler::getInstance('Application');
     JDEBUG ? $profiler->mark('processToDb: start') : null;
     $pluginManager = FabrikWorker::getPluginManager();
     $listModel = $this->getListModel();
     $origId = $this->prepareForCopy();
     $this->formData = $listModel->removeTableNameFromSaveData($this->formData, '___');
     JDEBUG ? $profiler->mark('processToDb, submitToDatabase: start') : null;
     $insertId = $this->storeMainRow ? $this->submitToDatabase($this->rowId) : $this->rowId;
     $this->updateReferrer($origId, $insertId);
     $this->setInsertId($insertId);
     // Store join data
     JDEBUG ? $profiler->mark('processToDb, processGroups: start') : null;
     $this->processGroups($insertId);
     // Enable db join checkboxes in repeat groups to save data
     JDEBUG ? $profiler->mark('processToDb, processElements: start') : null;
     $this->processElements();
     JDEBUG ? $profiler->mark('processToDb, onBeforeCalculations plugins: start') : null;
     if (in_array(false, $pluginManager->runPlugins('onBeforeCalculations', $this))) {
         return $insertId;
     }
     JDEBUG ? $profiler->mark('processToDb, doCalculations: start') : null;
     $this->listModel->doCalculations();
     JDEBUG ? $profiler->mark('processToDb: end') : null;
     return $insertId;
 }
Exemple #2
0
 /**
  * Process the form to the database
  *
  * @return void
  */
 public function processToDB()
 {
     $pluginManager = FabrikWorker::getPluginManager();
     $app = JFactory::getApplication();
     $input = $app->input;
     $listModel = $this->getListModel();
     $item = $listModel->getTable();
     $origid = $this->prepareForCopy();
     $this->formData = $listModel->removeTableNameFromSaveData($this->formData, '___');
     $insertId = $this->storeMainRow ? $this->submitToDatabase($this->rowId) : $this->rowId;
     $this->updateRefferrer($origid, $insertId);
     $this->setInsertId($insertId);
     // Store join data
     $this->processGroups();
     // Enable db join checkboxes in repeat groups to save data
     $this->processElements();
     if (in_array(false, $pluginManager->runPlugins('onBeforeCalculations', $this))) {
         return $insertId;
     }
     $this->listModel->doCalculations();
     return $insertId;
 }
Exemple #3
0
 /**
  * Process the data to the database
  *
  * @return null
  */
 public function processToDB()
 {
     $listModel = $this->getListModel();
     $listModel->setBigSelects();
     $item = $listModel->getTable();
     $origTableName = $item->db_table_name;
     $origTableKey = $item->db_primary_key;
     $pluginManager = FabrikWorker::getPluginManager();
     // COPY function should create new records
     if (array_key_exists('Copy', $this->_formData)) {
         $this->_rowId = '';
         // $$$ rob dont pass in $item->db_primary_key directly into safeColName as its then
         // modified permanently by this function
         $k = $item->db_primary_key;
         $k = FabrikString::safeColNameToArrayKey($k);
         $origid = $this->_formData[$k];
         $this->_formData[$k] = '';
         $this->_formData['rowid'] = '';
     }
     /* get an array of the joins to process
     		 note this was processJoin() but now preProcessJoin() does the same except
     		no longer stores the results - do this after the main form data has been
     		saved and u have an id to use
     		for the foreign key value*/
     $aPreProcessedJoins = $listModel->preProcessJoin();
     $joinKeys = array();
     /* Needed for plugins that are run after the data is submitted to the db
      * $$$ rob moved to outside processToDB() as this data is needed regardless of
      * whether we store in the db or not (for email data)
      * $this->_formDataWithTableName = $this->_formData;
      */
     $this->_formData = $listModel->removeTableNameFromSaveData($this->_formData, '___');
     if ($this->_storeMainRow) {
         $insertId = $this->submitToDatabase($this->_rowId);
     } else {
         $insertId = $this->_rowId;
     }
     // Set the redirect page to the form's url if making a copy and set the id
     // to the new insertid
     if (array_key_exists('Copy', $this->_formData)) {
         $u = str_replace('rowid=' . $origid, 'rowid=' . $insertId, JRequest::getVar('HTTP_REFERER', '', 'server'));
         JRequest::setVar('fabrik_referrer', $u);
     }
     $tmpKey = str_replace("`", "", $item->db_primary_key);
     $joinKeys[$tmpKey] = $insertId;
     $tmpKey = str_replace('.', '___', $tmpKey);
     $this->_formData[$tmpKey] = $insertId;
     $this->_formData[$tmpKey . '_raw'] = $insertId;
     $this->_formData[FabrikString::shortColName($item->db_primary_key)] = $insertId;
     $this->_formData[FabrikString::shortColName($item->db_primary_key) . '_raw'] = $insertId;
     // Need for things like the redirect plugin
     $this->_fullFormData[$tmpKey] = $insertId;
     $this->_fullFormData[$tmpKey . '_raw'] = $insertId;
     $this->_fullFormData['rowid'] = $insertId;
     $this->_formData['rowid'] = $insertId;
     $this->_formDataWithTableName['rowid'] = $insertId;
     $_REQUEST[$tmpKey] = $insertId;
     $_POST[$tmpKey] = $insertId;
     $_POST['rowid'] = $insertId;
     $_REQUEST['rowid'] = $insertId;
     // $$$ hugh - pretty sure we need to unset 'usekey' now, as it is not relavent to joined data,
     // and it messing with storeRow of joins
     JRequest::setVar('usekey', '');
     $_POST['usekey'] = '';
     $_REQUEST['usekey'] = '';
     // Save join data
     $this->_removeIgnoredData($this->_formData);
     $aDeleteRecordId = '';
     // $$$ hugh - can't do this, as might be repeat element with no data,
     // like checkbox join with no selections, and no other joins on form
     if (!isset($this->_formData['join'])) {
         $this->_formData['join'] = array();
     }
     foreach ($aPreProcessedJoins as $tmpJKey => $aPreProcessedJoin) {
         if (!array_key_exists('join', $aPreProcessedJoin)) {
             continue;
         }
         $oJoin = $aPreProcessedJoin['join'];
         // 3.0 test on repeatElement param type
         if (is_string($oJoin->params)) {
             $oJoin->params = json_decode($oJoin->params);
         }
         if (!isset($oJoin->params->pk) || empty($oJoin->params->pk)) {
             $cols = $joinDb->getTableColumns($oJoin->table_join, false);
             $oJoinPk = $oJoin->table_join . '___';
             foreach ($cols as $col) {
                 if ($col->Key == 'PRI') {
                     $oJoinPk .= $col->Field;
                 }
             }
         } else {
             $oJoinPk = FabrikString::safeColNameToArrayKey($oJoin->params->pk);
         }
         if (array_key_exists('Copy', $this->_formData)) {
             $this->_rowId = '';
             /* $$$ hugh - nope, this is wrong, builds the wrong element name, we need to use the join's PK, not it's FK,
              * so we need the new 'pk' param if available, or build it from first principles.
              * So ... moved that code to just above, where we now build the oJoinPk.
              * $this->_formData['join'][$oJoin->id][$oJoin->table_join . '___' . $oJoin->table_key] = '';
              */
             if (is_array($this->_formData['join'][$oJoin->id][$oJoinPk])) {
                 foreach ($this->_formData['join'][$oJoin->id][$oJoinPk] as &$ojpk) {
                     $ojpk = '';
                 }
             } else {
                 $this->_formData['join'][$oJoin->id][$oJoinPk] = '';
             }
             $this->_formData['rowid'] = '';
         }
         // $$$ rob 22/02/2011 could be a mutlfileupload with no images selected?
         if (!array_key_exists($oJoin->id, $this->_formData['join'])) {
             // Continue;
         }
         $data = FArrayHelper::getValue($this->_formData['join'], $oJoin->id, array(), 'array');
         $groups = $this->getGroupsHiarachy();
         $repeatTotals = JRequest::getVar('fabrik_repeat_group', array(0), 'post', 'array');
         $joinType = isset($oJoin->params->type) ? $oJoin->params->type : '';
         if ((int) $oJoin->group_id !== 0 && $joinType !== 'repeatElement') {
             $joinGroup = $groups[$oJoin->group_id];
             // Find the primary key for the join table
             $listModel->getTable()->db_table_name = $oJoin->table_join;
         } else {
             // Repeat element join
             $elementModel = $this->getElement($oJoin->element_id, true);
             /* $$$ hugh - covers case where repeat element is read only,
              * so isn't submitting any join data, versus editable element
              * which is empty (like checkbox join), so isn't submitting any data.
              */
             if (!$elementModel->canUse()) {
                 continue;
             }
             $joinGroup = JModel::getInstance('Group', 'FabrikFEModel');
             /* Need to set the fake group's form and id to that of the current elements form/group
              * $joinGroup->set('_form', $this);
              * $joinGroup->setId($elementModel->getGroup()->getId());
              */
             $joinGroup->getGroup()->id = -1;
             $joinGroup->getGroup()->is_join = 1;
             // Set join groups repeat to that of the elements options
             if ($elementModel->isJoin()) {
                 $joinGroup->getParams()->set('repeat_group_button', 1);
                 // Set repeat count
                 if ($elementModel->getGroup()->isJoin()) {
                     // Repeat element in a repeat group :S
                     $groupJoin = $elementModel->getGroup()->getJoinModel();
                     $dataPks = JArrayHelper::getValue($data, $oJoin->table_join . '___id', array());
                     for ($r = 0; $r < count($dataPks); $r++) {
                         $repeatTotals['el' . $elementModel->getId()][$r] = count($dataPks[$r]);
                     }
                 } else {
                     $repeatTotals[$oJoin->group_id] = $elementModel->getJoinRepeatCount($data, $oJoin);
                 }
             } else {
                 // "Not a repeat element (el id = $oJoin->element_id)<br>";
             }
             // Copy the repeating element into the join group
             $idElementModel = FabrikHelperElement::makeIdElement($elementModel);
             $parentElement = FabrikHelperElement::makeParentElement($elementModel);
             $joinGroup->publishedElements = array();
             $joinGroup->publishedElements[''] = array($elementModel, $idElementModel, $parentElement);
             $data[$oJoin->table_join . '___' . $oJoin->table_join_key] = JArrayHelper::getValue($repeatTotals, $oJoin->group_id, 0) === 0 ? array() : array_fill(0, $repeatTotals[$oJoin->group_id], $insertId);
             $this->groups[] = $joinGroup;
             $listModel->getTable()->db_table_name = $oJoin->table_join;
         }
         $joinGroupTable = $joinGroup->getGroup();
         // $$$ rob - erm is $fields needed?
         $fields = $listModel->getDBFields($listModel->getTable()->db_table_name);
         $aKey = $listModel->getPrimaryKeyAndExtra();
         if (!$aKey) {
             // $$$ hugh - most likely a view, so lets not try and store it
             continue;
         }
         $aKey = $aKey[0];
         $listModel->getTable()->db_primary_key = $aKey['colname'];
         $joinDb = $listModel->getDb();
         // Back on track
         if (is_array($data) && array_key_exists($oJoin->table_join . '___' . $oJoin->table_join_key, $data)) {
             $fullforeginKey = $oJoin->table_join . '___' . $oJoin->table_join_key;
             $repeatParams = array();
             $paramKey = $listModel->getTable()->db_table_name . '___params';
             $repeatParams = JArrayHelper::getValue($data, $paramKey, array());
             if ($joinGroup->canRepeat()) {
                 // Find out how many repeated groups were entered
                 $repeatedGroupCount = JArrayHelper::getValue($repeatTotals, $oJoin->group_id, 0, 'int');
                 $elementModels = $joinGroup->getPublishedElements();
                 $aUpdatedRecordIds = array();
                 $joinCnn = $listModel->getConnection();
                 $joinDb = $joinCnn->getDb();
                 for ($c = 0; $c < $repeatedGroupCount; $c++) {
                     // Get the data for each group and record it seperately
                     $repData = array();
                     foreach ($elementModels as $elementModel) {
                         $element = $elementModel->getElement();
                         $n = $elementModel->getFullName(false, true, false);
                         $v = array_key_exists($n, $data) && is_array($data[$n]) && array_key_exists($c, $data[$n]) ? $data[$n][$c] : '';
                         $repData[$element->name] = $v;
                         $n_raw = $n . '_raw';
                         // $$$ rob 11/04/2012 - repeat elements don't have raw values so use the value as the default raw value
                         $defaultRaw = $joinType == 'repeatElement' ? $v : '';
                         $v_raw = array_key_exists($n_raw, $data) && is_array($data[$n_raw]) && array_key_exists($c, $data[$n_raw]) ? $data[$n_raw][$c] : $defaultRaw;
                         $repData[$element->name . '_raw'] = $v_raw;
                         // Store any params set in the individual plug-in (see fabrikfileupload::processUpload()->crop()
                         $thisRepeatParams = JArrayHelper::getValue($repeatParams, $c);
                         if (!is_null($thisRepeatParams) && $elementModel->isJoin()) {
                             $repData['params'] = $thisRepeatParams;
                         }
                     }
                     // $$$ rob didn't work for 2nd joined data set
                     // $repData[$oJoin->table_join_key] = $insertId;
                     unset($repData[$oJoin->table_join_key . '_raw']);
                     $listJoinKey = $oJoin->join_from_table . '.' . $oJoin->table_key;
                     $repData[$oJoin->table_join_key] = JArrayHelper::getValue($joinKeys, $listJoinKey, $insertId);
                     // $$$ rob test for issue with importing joined csv data
                     if (is_array($repData[$oJoin->table_join_key])) {
                         $repData[$oJoin->table_join_key] = $repData[$oJoin->table_join_key][$c];
                     }
                     // Find the primary key for the join table
                     $item->db_table_name = $oJoin->table_join;
                     // $$$ rob - erm is $fields needed -perhaps just pass $item->db_table_name into getPrimaryKeyAndExtra?
                     $fields = $listModel->getDBFields($item->db_table_name);
                     $aKey = $listModel->getPrimaryKeyAndExtra();
                     $aKey = $aKey[0];
                     $item->db_primary_key = $aKey['colname'];
                     $joinRowId = $repData[$item->db_primary_key];
                     $aDeleteRecordId = $joinDb->Quote($repData[$oJoin->table_join_key]);
                     /* $$$ hugh - need to give it the table name!!
                      * $$$ rob no no no this is not the issue, on SOME setups $item is NOT a reference to $listModel->_table - this is where the issue is
                      * not passing in the correct table name - see notes line 720 for explaination
                      * $listModel->storeRow($repData, $joinRowId, true, $item->db_table_name);
                      */
                     $listModel->storeRow($repData, $joinRowId, true, $joinGroupTable);
                     if ((int) $joinRowId === 0) {
                         $joinRowId = $listModel->lastInsertId;
                         // $$$ hugh - need to set PK element value for things like email plugin
                         $this->_formData['join'][$oJoin->id][$oJoinPk][$c] = $joinRowId;
                         $this->_formDataWithTableName['join'][$oJoin->id][$oJoinPk][$c] = $joinRowId;
                         $this->_fullFormData['join'][$oJoin->id][$oJoinPk][$c] = $joinRowId;
                         $this->_formData['join'][$oJoin->id][$oJoinPk . '_raw'][$c] = $joinRowId;
                         $this->_formDataWithTableName['join'][$oJoin->id][$oJoinPk . '_raw'][$c] = $joinRowId;
                     }
                     $aUpdatedRecordIds[] = $joinRowId;
                     $tmpKey = $oJoin->table_join . '.' . $oJoin->table_key;
                     $joinKeys[$tmpKey] = $listModel->lastInsertId;
                 }
                 $query = $joinDb->getQuery(true);
                 if ($repeatedGroupCount === 0) {
                     // All repeat group data was removed
                     $query->delete($oJoin->table_join)->where("{$oJoin->table_join_key} = {$insertId}");
                 } else {
                     // Remove any joins that have been deleted with the groups "delete" button
                     if (!$data) {
                         $query->delete($oJoin->table_join)->where("{$oJoin->table_join_key} = {$aDeleteRecordId}");
                     } else {
                         $updateIds = implode(',', $aUpdatedRecordIds);
                         $query->delete($oJoin->table_join)->where("!({$item->db_primary_key} IN (" . $updateIds . ")) AND ({$oJoin->table_join_key} = {$aDeleteRecordId})");
                     }
                 }
                 $joinDb->setQuery($query);
                 $joinDb->query();
             } else {
                 /* $$$ hugh - trying to get one-to-one joins working where parent.fk = child.pk (ie where parent points to child)
                  * So ... if we have that situation, what we will see next is
                  *
                  * if (($fullforeginKey != $oJoinPk || (int) $data['rowid'] === 0)
                  * && ($fullforeginKey != "{$oJoin->table_join}___{$oJoin->table_key}" || $oJoin->table_key === $oJoin->table_join_key)) {}
                  *
                  * which we need NOT to be true, otherwise (as per Rob's comment) we'll actually be overwriting the PK.
                  * Then, after that we are going to see ...
                  * if ($fullforeginKey == $oJoinPk) {}
                  * which needs to be true in order for the code to go back and write the new joined rows PK
                  * into the parenjt's FK element.
                  * So ... although it doesn't really make sense, in the one-to-one, parent.fk = child.pk scenario,
                  * we need $fullforeginKey to be the same as $oJoinPk.  So we need to work out if the FK is on parent or child ...
                  * Which I think means testing to see if the $oJoinPk == $oJoin->table_join + $oJoin->table_join_key.
                  * if it does, then element the user selected on the joined (child) table is NOT the FK.  Which means
                  * the FK is actually the element they selected on the main table (parent).  In which case, we need to set
                  * $fullforeginKey = $oJoinPk, which although it isn't, will satisfy the following code!!
                  */
                 if ($oJoinPk == $oJoin->table_join . '___' . $oJoin->table_join_key) {
                     $fullforeginKey = $oJoinPk;
                 }
                 /* $$$rob test if the joined to table's key (as part of the join) is the same as its primary key
                  * if it is then we dont want to overwrite the foreginkey as we will in fact be overwriting the pk
                  *
                  * $$$ rob - 1) altered now so that this test only returns true if we are editing an existing record
                  *
                  * 2) also test if the foreign key isnt the same as the joins key - hard to explain cos its v confusing but
                  * when you had 2 joins with both of them key'd to the main table things went horribly wrong
                  * if (($fullforeginKey != $oJoinPk || (int) $data['rowid'] === 0) && $fullforeginKey != "{$oJoin->table_join}___{$oJoin->table_key}") {
                  * $$$ rob - 3) hmm (2) was incorrect if your table had a pk called the same as the joined table's fk - eg.
                  * tbl, venture pk venture_id, tbl access, fk venture_id
                  * $$$ hugh - FIXME - something in this is hosing up when creating new one-to-one record where
                  * parent.fk points to child.pk
                  * OK, tried but couldn't understand why the rowid==0 test, which seems to make it impossible to do.  Trying without this.
                  * Seems to work (with my change above) without the rowid test, for edit/new
                  */
                 if ($fullforeginKey != $oJoinPk && ($fullforeginKey != $oJoin->table_join . '___' . $oJoin->table_key || $oJoin->table_key === $oJoin->table_join_key)) {
                     /* $$$ hugh - at this point we are assuming that we have a situation where the FK is on the joined table,
                      * pointing to PK on main table.  BUT ... we may have a situation where neither of the selected keys are
                      * a PK, i.e. two records are joined by some other field.  In which case we do not want to set the FK val!
                      * So, we need some logic here to handle that!
                      * $$$ hugh - OK, I think this is the test we need to see if neither ends of the join are a PK,
                      * and if so, don't modify any data, as we're joining on some other field that isn't the PK of either table.
                      */
                     /* $$$ Jaanus: tested succesfully one idea to allow to write next step joins fk, eg when joined table is joined to
                      * joined table.
                      * Yet not tested whether it works also with 3rd, 4th etc step joins. But I can confirm it hasn't any impact to
                      * the rather rarely used "parent.fk points to child.pk" case (that I got fully work only by using mysql trigger).
                      * Anyway, most important is that we got data submission work with joins table1->table2->table3->table# :)
                      * The following "if" prevented it so I commented it out.
                      */
                     /*if ($oJoin->join_from_table . '.' . $oJoin->table_key == $origTableKey)
                     		{*/
                     $fkVal = JArrayHelper::getValue($joinKeys, $oJoin->join_from_table . '.' . $oJoin->table_key, $insertId);
                     $data[$fullforeginKey] = $fkVal;
                     $data[$fullforeginKey . '_raw'] = $fkVal;
                     // }
                 }
                 if ($item->db_primary_key == '') {
                     return JError::raiseWarning(500, JText::_('COM_FABRIK_MUST_SELECT_PRIMARY_KEY'));
                 }
                 $joinRowId = $data[$item->db_table_name . '___' . $item->db_primary_key];
                 $data = $listModel->removeTableNameFromSaveData($data);
                 /* $$$ hugh - need to give it the table name!!
                  * $$$ rob no no no this is not the issue, on SOME setups $item is NOT a reference to $listModel->_table - this is where the issue is
                  * not passing in the correct table name - see notes line 720 for explaination
                  * $listModel->storeRow($repData, $joinRowId, true, $item->db_table_name);
                  */
                 $listModel->storeRow($data, $joinRowId, true, $joinGroupTable);
                 /* $$$ Les: shouldn't we store the row id of the newly stored row back in data?????
                  * Copied the following lines from the equivalent code for repeated groups
                  * ...removing the $c group counter
                  */
                 if ($joinRowId == '') {
                     $joinRowId = $listModel->lastInsertId;
                     $this->_formData['join'][$oJoin->id][$oJoinPk] = $joinRowId;
                     $this->_formDataWithTableName['join'][$oJoin->id][$oJoinPk] = $joinRowId;
                     $this->_fullFormData['join'][$oJoin->id][$oJoinPk] = $joinRowId;
                     $this->_formData['join'][$oJoin->id][$oJoinPk . '_raw'] = $joinRowId;
                     $this->_formDataWithTableName['join'][$oJoin->id][$oJoinPk . '_raw'] = $joinRowId;
                 }
                 /* $$$rob if the fk was the same as the pk then go back to the main table and
                  * update its fk to match the
                  * pk of the inserted table
                  */
                 // $$$ hugh - FIXME another point where things aren't right for one-to-one
                 // where parent.fk = child.pk
                 if ($fullforeginKey == $oJoinPk) {
                     $pkVal = $listModel->lastInsertId;
                     $fk = $oJoin->table_key;
                     $this->_formData[$fk] = $pkVal;
                     // Because storeRow takes _raw if the key exists, which it does
                     $this->_formData[$fk . '_raw'] = $pkVal;
                     /* Reset the table's values to the main table
                      * $$$ rob same issues as above with $item not being a reference to $listModel->_table
                      * $item->db_table_name = $origTableName;
                      * $item->db_primary_key = $origTableKey;
                      */
                     $listModel->getTable()->db_table_name = $origTableName;
                     $listModel->getTable()->db_primary_key = $origTableKey;
                     $listModel->storeRow($this->_formData, $insertId);
                     $insertId = $listModel->lastInsertId;
                 }
                 $tmpKey = $oJoin->table_join . '.' . $oJoin->table_key;
                 $joinKeys[$tmpKey] = $listModel->lastInsertId;
             }
         } else {
             // No join data found so delete all joined records
             $k = $oJoin->join_from_table . '___' . $oJoin->table_key;
             $delPkVal = JArrayHelper::getValue($this->_formData, $k, '');
             if ($delPkVal !== '') {
                 $query = $joinDb->getQuery(true);
                 $query->delete($oJoin->table_join)->where("({$oJoin->table_join_key} = {$delPkVal})");
                 $joinDb->setQuery($query);
                 $joinDb->query();
             }
         }
     }
     // Testing for saving pages
     JRequest::setVar('rowid', $insertId);
     if (in_array(false, $pluginManager->runPlugins('onBeforeCalculations', $this))) {
         return;
     }
     $this->_listModel->doCalculations();
 }