/** * Clone the record * * @param object $params plugin params * @param object &$formModel form model * * @return bool */ private function _process($params, &$formModel) { $clone_times_field_id = $params->get('clone_times_field', ''); $clone_batchid_field_id = $params->get('clone_batchid_field', ''); if ($clone_times_field_id != '') { $elementModel = FabrikWorker::getPluginManager()->getElementPlugin($clone_times_field_id); $element = $elementModel->getElement(true); if ($clone_batchid_field_id != '') { $elementModel = FabrikWorker::getPluginManager()->getElementPlugin($clone_batchid_field_id); $id_element = $id_elementModel->getElement(true); $formModel->_formData[$id_element->name] = $formModel->_fullFormData['rowid']; $formModel->_formData[$id_element->name . '_raw'] = $formModel->_fullFormData['rowid']; $listModel = $formModel->getlistModel(); $listModel->_oForm = $formModel; $primaryKey = FabrikString::shortColName($listModel->getTable()->db_primary_key); $formModel->_formData[$primaryKey] = $formModel->_fullFormData['rowid']; $formModel->_formData[$primaryKey . '_raw'] = $formModel->_fullFormData['rowid']; $listModel->storeRow($formModel->_formData, $formModel->_fullFormData['rowid']); } // $clone_times_field = $elementModel->getFullName(false, true, false); $clone_times = $formModel->_formData[$element->name]; if (is_numeric($clone_times)) { $clone_times = (int) $clone_times; $formModel->_formData['Copy'] = 1; for ($x = 1; $x < $clone_times; $x++) { $formModel->processToDB(); } return true; } } JError::raiseNotice(JText::_('CLONEERR'), "Couldn't find a valid number of times to clone!"); return true; }
/** * Clone the record * * @return bool */ private function _process() { $params = $this->getParams(); /** @var FabrikFEModelForm $formModel */ $formModel = $this->getModel(); $clone_times_field_id = $params->get('clone_times_field', ''); $clone_batchid_field_id = $params->get('clone_batchid_field', ''); if ($clone_times_field_id != '') { $elementModel = FabrikWorker::getPluginManager()->getElementPlugin($clone_times_field_id); $element = $elementModel->getElement(true); if ($clone_batchid_field_id != '') { $elementModel = FabrikWorker::getPluginManager()->getElementPlugin($clone_batchid_field_id); $id_element = $elementModel->getElement(true); $formModel->formData[$id_element->name] = $formModel->fullFormData['rowid']; $formModel->formData[$id_element->name . '_raw'] = $formModel->fullFormData['rowid']; $listModel = $formModel->getlistModel(); $listModel->setFormModel($formModel); $primaryKey = FabrikString::shortColName($listModel->getPrimaryKey()); $formModel->formData[$primaryKey] = $formModel->fullFormData['rowid']; $formModel->formData[$primaryKey . '_raw'] = $formModel->fullFormData['rowid']; $listModel->storeRow($formModel->formData, $formModel->fullFormData['rowid']); } $clone_times = $formModel->formData[$element->name]; if (is_numeric($clone_times)) { $clone_times = (int) $clone_times; $formModel->formData['Copy'] = 1; for ($x = 1; $x < $clone_times; $x++) { $formModel->processToDB(); } return true; } } throw new RuntimeException("Couldn't find a valid number of times to clone!"); }
/** * get the field name to use as the column that contains the join's label data * @param bol use step in element name * @return string join label column either returns concat statement or quotes `tablename`.`elementname` */ function getJoinLabelColumn($useStep = false) { $params = $this->getParams(); $join = $this->getJoin(); if (($params->get('cascadingdropdown_label_concat') != '') && JRequest::getVar('overide_join_val_column_concat') != 1) { $val = str_replace("{thistable}", $join->table_join_alias, $params->get('cascadingdropdown_label_concat')); return "CONCAT(".$val.")"; } $label = FabrikString::shortColName($join->_params->get('join-label')); if ($label == '') { JError::raiseWarning(500, 'Could not find the join label for '.$this->getElement()->name . ' try unlinking and saving it'); $label = $this->getElement()->name; } $joinTableName = $join->table_join_alias; return $useStep ? $joinTableName.'___'.$label : "`$joinTableName`.`$label`"; }
private function _process(&$params, &$formModel ) { $user = JFactory::getUser(); $db = FabrikWorker::getDbo(); if ($params->get('limit_allow_anonymous')) { return true; } if (JRequest::getCmd('view') === 'details') { return true; } $listid = (int)$params->get('limit_table'); if ($listid === 0) { //use the limit setting supplied in the admin params $limit = (int)$params->get('limit_length'); } else { //look up the limit from the table spec'd in the admin params $listModel = JModel::getInstance('List', 'FabrikFEModel'); $listModel->setId($listid); $max = $db->NameQuote(FabrikString::shortColName($params->get('limit_max'))); $userfield = $db->NameQuote(FabrikString::shortColName($params->get('limit_user'))); $db->setQuery("SELECT $max FROM " . $listModel->getTable()->db_table_name . " WHERE $userfield = " . (int)$user->get('id')); $limit = (int)$db->loadResult(); } $field = $params->get('limit_userfield'); $listModel = $formModel->getlistModel(); $list = $listModel->getTable(); $db = $listModel->getDb(); $db->setQuery("SELECT COUNT($field) FROM $list->db_table_name WHERE $field = " . (int)$user->get('id')); $c = $db->loadResult(); if ($c >= $limit) { $msg = $params->get('limit_reached_message'); $msg = str_replace('{limit}', $limit, $msg); JError::raiseNotice(1, $msg); return false; } else { $app = JFactory::getApplication(); $app->enqueueMessage(JText::sprintf('ENTRIES_LEFT_MESSAGE', $limit - $c, $limit)); } return true; }
/** * Process the plugin * * @param object $params plugin params * @param object &$formModel form model * * @return bool */ private function _process($params, &$formModel) { $user = JFactory::getUser(); $db = FabrikWorker::getDbo(); $query = $db->getQuery(true); if ($params->get('limit_allow_anonymous')) { return true; } if (JRequest::getCmd('view') === 'details' || $formModel->getRowId() > 0) { return true; } $listid = (int) $params->get('limit_table'); if ($listid === 0) { // Use the limit setting supplied in the admin params $limit = (int) $params->get('limit_length'); } else { // Look up the limit from the table spec'd in the admin params $listModel = JModel::getInstance('List', 'FabrikFEModel'); $listModel->setId($listid); $max = $db->quoteName(FabrikString::shortColName($params->get('limit_max'))); $userfield = $db->quoteName(FabrikString::shortColName($params->get('limit_user'))); $query->select($max)->from($listModel->getTable()->db_table_name)->where($userfield . ' = ' . (int) $user->get('id')); $db->setQuery($query); $limit = (int) $db->loadResult(); } $field = $params->get('limit_userfield'); $listModel = $formModel->getlistModel(); $list = $listModel->getTable(); $db = $listModel->getDb(); $query->clear()->select(' COUNT(' . $field . ')')->from($list->db_table_name)->where($field . ' = ' . (int) $user->get('id')); $db->setQuery($query); $c = $db->loadResult(); if ($c >= $limit) { $msg = $params->get('limit_reached_message', JText::sprintf('PLG_FORM_LIMIT_LIMIT_REACHED', $limit)); $msg = str_replace('{limit}', $limit, $msg); JError::raiseNotice(1, $msg); return false; } else { $app = JFactory::getApplication(); $app->enqueueMessage(JText::sprintf('PLG_FORM_LIMIT_ENTRIES_LEFT_MESSAGE', $limit - $c, $limit)); } return true; }
/** * Get the label parameter's value * * @return string */ protected function getLabelParamVal() { if (isset($this->labelParamVal)) { return $this->labelParamVal; } $params = $this->getParams(); $label = $params->get($this->labelParam); $label = FabrikString::shortColName($label); $this->labelParamVal = $label; return $this->labelParamVal; }
/** * Set various request / input arrays with the main records insert id * * @param string $insertId The records insert id * * @return void */ public function setInsertId($insertId) { $input = $this->app->input; $listModel = $this->getListModel(); $item = $listModel->getTable(); $tmpKey = str_replace("`", "", $item->db_primary_key); $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; $this->fullFormData[$tmpKey] = $insertId; $this->fullFormData[$tmpKey . '_raw'] = $insertId; $this->fullFormData['rowid'] = $insertId; $this->formData['rowid'] = $insertId; $this->formDataWithTableName[$tmpKey] = $insertId; $this->formDataWithTableName[$tmpKey . '_raw'] = $insertId; $this->formDataWithTableName['rowid'] = $insertId; $input->set($tmpKey, $insertId); $input->set('rowid', $insertId); // $$$ hugh - pretty sure we need to unset 'usekey' now, as it is not relevant to joined data, // and it messing with storeRow of joins $input->set('usekey', ''); }
function save($data) { jimport('joomla.utilities.date'); $user = JFactory::getUser(); $app = JFactory::getApplication(); $new = $data['id'] == 0 ? true : false; $params = $data['params']; $data['name'] = FabrikString::iclean($data['name']); $name = $data['name']; $params['validations'] = JArrayHelper::getValue($data, 'validationrule', array()); $elementModel = $this->getElementPluginModel($data); $row = $elementModel->getElement(); if ($new) { //have to forcefully set group id otherwise listmodel id is blank $elementModel->getElement()->group_id = $data['group_id']; } $listModel = $elementModel->getListModel(); $item = $listModel->getTable(); //are we updating the name of the primary key element? if ($row->name === FabrikString::shortColName($item->db_primary_key)) { if ($name !== $row->name) { //yes we are so update the table $item->db_primary_key = str_replace($row->name, $name, $item->db_primary_key); $item->store(); } } $jsons = array('sub_values', 'sub_labels', 'sub_initial_selection'); foreach ($jsons as $json) { if (array_key_exists($json, $data)) { $data[$json] = json_encode($data[$json]); } } //only update the element name if we can alter existing columns, otherwise the name and //field name become out of sync $data['name'] = $listModel->canAlterFields() || $new ? $name : JRequest::getVar('name_orig', '', 'post', 'cmd'); $ar = array('published', 'use_in_page_title', 'show_in_list_summary', 'link_to_detail', 'can_order', 'filter_exact_match'); foreach ($ar as $a) { if (!array_key_exists($a, $data)) { $data[$a] = 0; } } // $$$ rob - test for change in element type //(eg if changing from db join to field we need to remove the join //entry from the #__{package}_joins table // @TODO test this for j1.6 $elementModel->beforeSave($row); //unlink linked elements if (JRequest::getVar('unlink') == 'on') { $data['parent_id'] = 0; } $datenow = new JDate(); if ($row->id != 0) { $data['modified'] = $datenow->toSql(); $data['modified_by'] = $user->get('id'); } else { $data['created'] = $datenow->toSql(); $data['created_by'] = $user->get('id'); $data['created_by_alias'] = $user->get('username'); } $data['params'] = json_encode($params); $cond = 'group_id = ' . (int) $row->group_id; if ($new) { $data['ordering'] = $row->getNextOrder($cond); } $row->reorder($cond); $this->updateChildIds($row); $elementModel->getElement()->bind($data); $origName = JRequest::getVar('name_orig', '', 'post', 'cmd'); list($update, $q, $oldName, $newdesc, $origDesc) = $listModel->shouldUpdateElement($elementModel, $origName); if ($update) { $origplugin = JRequest::getVar('plugin_orig'); $config = JFactory::getConfig(); $prefix = $config->getValue('dbprefix'); $tablename = $listModel->getTable()->db_table_name; $hasprefix = strstr($tablename, $prefix) === false ? false : true; $tablename = str_replace($prefix, '#__', $tablename); if (in_array($tablename, $this->core)) { $app->enqueueMessage(JText::_('COM_FABRIK_WARNING_UPDATE_CORE_TABLE'), 'notice'); } else { if ($hasprefix) { $app->enqueueMessage(JText::_('COM_FABRIK_WARNING_UPDATE_TABLE_WITH_PREFIX'), 'notice'); } } $app->setUserState('com_fabrik.confirmUpdate', 1); $app->setUserState('com_fabrik.plugin_orig', $origplugin); $app->setUserState('com_fabrik.q', $q); $app->setUserState('com_fabrik.newdesc', $newdesc); $app->setUserState('com_fabrik.origDesc', $origDesc); $app->setUserState('com_fabrik.origplugin', $origplugin); $app->setUserState('com_fabrik.oldname', $oldName); $app->setUserState('com_fabrik.origtask', JRequest::getCmd('task')); $app->setUserState('com_fabrik.plugin', $data['plugin']); $task = JRequest::getCmd('task'); $app->setUserState('com_fabrik.redirect', 'index.php?option=com_fabrik&view=element&layout=confirmupdate&id=' . (int) $row->id . "&origplugin={$origplugin}&&origtaks={$task}&plugin={$row->plugin}"); } else { $app->setUserState('com_fabrik.confirmUpdate', 0); } if ((int) $listModel->getTable()->id !== 0) { $this->updateIndexes($elementModel, $listModel, $row); } $return = parent::save($data); if ($return) { $this->updateJavascript($data); $elementModel->_id = $this->getState($this->getName() . '.id'); $row->id = $elementModel->_id; $this->createRepeatElement($elementModel, $row); // If new, check if the element's db table is used by other tables and if so add the element // to each of those tables' groups if ($new) { $this->addElementToOtherDbTables($elementModel, $row); } if (!$elementModel->onSave($data)) { $this->setError(JText::_('COM_FABRIK_ERROR_SAVING_ELEMENT_PLUGIN_OPTIONS')); return false; } } return $return; //used for prefab //return $elementModel; }
/** * Trigger called when a row is stored. * If toggle_others on then set other records yesno value to 0 * * @param array &$data Data to store * @param int $repeatCounter Repeat group index * * @return void */ public function onStoreRow(&$data, $repeatCounter = 0) { if (!parent::onStoreRow($data, $repeatCounter)) { return false; } $value = $this->getValue($data, $repeatCounter); if ($value == '1') { $params = $this->getParams(); $toggle = (bool) $params->get('toggle_others', false); if ($toggle === false) { return; } $listModel = $this->getListModel(); $name = $this->getElement()->name; $db = $listModel->getDb(); $query = $db->getQuery(true); if ($this->isJoin()) { $joinModel = $this->getJoinModel(); $pk = $joinModel->getJoinedToTablePk('.'); } else { $pk = $listModel->getPrimaryKey(); } $shortPk = FabrikString::shortColName($pk); $rowId = FArrayHelper::getValue($data, $shortPk, null); $query->update($this->actualTableName())->set($name . ' = 0'); if (!empty($rowId)) { $query->where($pk . ' <> ' . $rowId); } $toggle_where = $params->get('toggle_where', ''); FabrikString::ltrimiword($toggle_where, 'where'); if (!empty($toggle_where)) { $w = new FabrikWorker(); $toggle_where = $w->parseMessageForPlaceHolder($toggle_where); $query->where($toggle_where); } $db->setQuery($query); $db->execute(); } }
/** * Internal function: add a key to the table * * @param string $fieldName primary key column name * @param bool $autoIncrement is the column auto incrementing * @param string $type the primary keys column type (if autoincrement true then int(6) is always used as the type) * * @return mixed false / JError */ private function addKey($fieldName, $autoIncrement, $type = "INT(6)") { $db = $this->getFEModel()->getDb(); $type = $autoIncrement != true ? $type : 'INT(6)'; $post = JRequest::get('post'); $tableName = $post['jform']['db_table_name'] != '' ? $post['jform']['db_table_name'] : $post['jform']['_database_name']; $tableName = preg_replace('#[^0-9a-zA-Z_]#', '_', $tableName); $tableName = FabrikString::safeColName($tableName); $fieldName = FabrikString::shortColName($fieldName); if ($fieldName === "") { return false; } $fieldName = $db->quoteName($fieldName); $sql = 'ALTER TABLE ' . $tableName . ' ADD PRIMARY KEY (' . $fieldName . ')'; /* add a primary key */ $db->setQuery($sql); if (!$db->query()) { return JError::raiseWarning(500, $db->getErrorMsg()); } if ($autoIncrement) { // Add the autoinc $sql = 'ALTER TABLE ' . $tableName . ' CHANGE ' . $fieldName . ' ' . $fieldName . ' ' . $type . ' NOT NULL AUTO_INCREMENT'; $db->setQuery($sql); if (!$db->query()) { return JError::raiseError(500, 'add key: ' . $db->getErrorMsg()); } } return true; }
function updateFabrikData() { if ($this->_isNew && $this->_articleId > 0) { $articleIdElementName = $this->_elementBaseName($this->_articleIdElement); $this->_formModel->_formData[$articleIdElementName] = $this->_articleId; $this->_formModel->_formData[$articleIdElementName . '_raw'] = $this->_articleId; $listModel = $this->_formModel->getlistModel(); $listModel->_oForm =& $this->_formModel; $primaryKey = FabrikString::shortColName($listModel->getTable()->db_primary_key); $this->_formModel->_formData[$primaryKey] = $this->_formModel->_fullFormData['rowid']; $this->_formModel->_formData[$primaryKey . '_raw'] = $this->_formModel->_fullFormData['rowid']; $listModel->storeRow($this->_formModel->_formData, $this->_formModel->_fullFormData['rowid']); } }
/** * Save an individual element value to the fabrik db * * @param string $rowId row id * @param string $key key * @param string $value value * * @return void */ public function storeCell($rowId, $key, $value) { $data[$key] = $value; // Ensure the primary key is set in $data $primaryKey = FabrikString::shortColName($this->getPrimaryKey()); $primaryKey = str_replace("`", "", $primaryKey); if (!isset($data[$primaryKey])) { $data[$primaryKey] = $rowId; } $this->storeRow($data, $rowId); }
/** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success, False on error. */ public function save($data) { $config = JComponentHelper::getParams('com_fabrik'); if ($config->get('fbConf_wysiwyg_label', 0) == 0) { // Ensure the data is in the same format as when saved by the wysiwyg element e.g. < becomes < $data['label'] = htmlspecialchars($data['label']); } jimport('joomla.utilities.date'); $input = $this->app->input; $new = $data['id'] == 0 ? true : false; $params = $data['params']; $data['name'] = FabrikString::iclean($data['name']); $name = $data['name']; $params['validations'] = FArrayHelper::getValue($data, 'validationrule', array()); $elementModel = $this->getElementPluginModel($data); $elementModel->getElement()->bind($data); $origId = $input->getInt('id'); $row = $elementModel->getElement(); if ($new) { // Have to forcefully set group id otherwise listmodel id is blank $elementModel->getElement()->group_id = $data['group_id']; } $listModel = $elementModel->getListModel(); $item = $listModel->getTable(); // Are we updating the name of the primary key element? if ($row->name === FabrikString::shortColName($item->db_primary_key)) { if ($name !== $row->name) { // Yes we are so update the table $item->db_primary_key = str_replace($row->name, $name, $item->db_primary_key); $item->store(); } } $jsons = array('sub_values', 'sub_labels', 'sub_initial_selection'); foreach ($jsons as $json) { if (array_key_exists($json, $data)) { $data[$json] = json_encode($data[$json]); } } // Only update the element name if we can alter existing columns, otherwise the name and field name become out of sync $data['name'] = $listModel->canAlterFields() || $new || $listModel->noTable() ? $name : $input->get('name_orig', ''); $ar = array('published', 'use_in_page_title', 'show_in_list_summary', 'link_to_detail', 'can_order', 'filter_exact_match'); foreach ($ar as $a) { if (!array_key_exists($a, $data)) { $data[$a] = 0; } } /** * $$$ rob - test for change in element type * (eg if changing from db join to field we need to remove the join * entry from the #__{package}_joins table */ $elementModel->beforeSave($row); // Unlink linked elements if ($input->get('unlink') == 'on') { $data['parent_id'] = 0; } $dateNow = new JDate(); if ($row->id != 0) { $data['modified'] = $dateNow->toSql(); $data['modified_by'] = $this->user->get('id'); } else { $data['created'] = $dateNow->toSql(); $data['created_by'] = $this->user->get('id'); $data['created_by_alias'] = $this->user->get('username'); } /** * $$$ hugh * This insane chunk of code is needed because the validation rule params are not in sequential, * completely indexed arrays. What we have is single item arrays, with specific numeric * keys, like foo-something[0], bar-otherthing[2], etc. And if you json_encode an array with incomplete * or out of sequence numeric indexes, it encodes it as an object instead of an array. Which means the first * validation plugin will encode as an array, as it's params are single [0] index, and the rest as objects. * This foobars things, as we then don't know if validation params are arrays or objects! * * One option would be to modify every validation, and test every param we use, and if necessary convert it, * but that would be a major pain in the ass. * * So ... we need to fill in the blanks in the arrays, and ksort them. But, we need to know the param names * for each validation. But as they are just stuck in with the rest of the element params, there is no easy * way of knowing which are validation params and which are element params. * * So ... we need to load the validation objects, then load the XML file for each one, and iterate through * the fieldsets! Well, that's the only way I could come up with doing it. Hopefully Rob can come up with * a quicker and simpler way of doing this! */ $validations = FArrayHelper::getValue($params['validations'], 'plugin', array()); $num_validations = count($validations); $validation_plugins = $this->getValidations($elementModel, $validations); foreach ($validation_plugins as $plugin) { $plugin_form = $plugin->getJForm(); JForm::addFormPath(JPATH_SITE . '/plugins/fabrik_validationrule/' . $plugin->get('pluginName')); $xmlFile = JPATH_SITE . '/plugins/fabrik_validationrule/' . $plugin->get('pluginName') . '/forms/fields.xml'; $xml = $plugin->jform->loadFile($xmlFile, false); foreach ($plugin_form->getFieldsets() as $fieldset) { foreach ($plugin_form->getFieldset($fieldset->name) as $field) { if (isset($params[$field->fieldname])) { if (is_array($params[$field->fieldname])) { for ($x = 0; $x < $num_validations; $x++) { if (!array_key_exists($x, $params[$field->fieldname])) { $params[$field->fieldname][$x] = ''; } } ksort($params[$field->fieldname]); } } } } } $data['params'] = json_encode($params); $row->params = $data['params']; $cond = 'group_id = ' . (int) $row->group_id; if ($new) { $data['ordering'] = $row->getNextOrder($cond); } $row->reorder($cond); /** * $$$ hugh - shouldn't updateChildIds() happen AFTER we save the main row? * Same place we do updateJavascript()? */ $this->updateChildIds($row); $elementModel->getElement()->bind($data); $origName = $input->get('name_orig', ''); list($update, $q, $oldName, $newdesc, $origDesc) = $listModel->shouldUpdateElement($elementModel, $origName); if ($update && $input->get('task') !== 'save2copy') { $origPlugin = $input->get('plugin_orig'); $prefix = $this->config->get('dbprefix'); $tableName = $listModel->getTable()->db_table_name; $hasPrefix = strstr($tableName, $prefix) === false ? false : true; $tableName = str_replace($prefix, '#__', $tableName); if (in_array($tableName, $this->core)) { $this->app->enqueueMessage(FText::_('COM_FABRIK_WARNING_UPDATE_CORE_TABLE'), 'notice'); } else { if ($hasPrefix) { $this->app->enqueueMessage(FText::_('COM_FABRIK_WARNING_UPDATE_TABLE_WITH_PREFIX'), 'notice'); } } $this->app->setUserState('com_fabrik.confirmUpdate', 1); $this->app->setUserState('com_fabrik.plugin_orig', $origPlugin); $this->app->setUserState('com_fabrik.q', $q); $this->app->setUserState('com_fabrik.newdesc', $newdesc); $this->app->setUserState('com_fabrik.origDesc', $origDesc); $this->app->setUserState('com_fabrik.origplugin', $origPlugin); $this->app->setUserState('com_fabrik.oldname', $oldName); $this->app->setUserState('com_fabrik.newname', $data['name']); $this->app->setUserState('com_fabrik.origtask', $input->get('task')); $this->app->setUserState('com_fabrik.plugin', $data['plugin']); $task = $input->get('task'); $url = 'index.php?option=com_fabrik&view=element&layout=confirmupdate&id=' . (int) $origId . '&origplugin=' . $origPlugin . '&origtask=' . $task . '&plugin=' . $row->plugin; $this->app->setUserState('com_fabrik.redirect', $url); } else { $this->app->setUserState('com_fabrik.confirmUpdate', 0); } if ((int) $listModel->getTable()->id !== 0) { $this->updateIndexes($elementModel, $listModel, $row); } $return = parent::save($data); if ($return) { $this->updateJavascript($data); $elementModel->setId($this->getState($this->getName() . '.id')); $row->id = $elementModel->getId(); $data['id'] = $row->id; $this->createRepeatElement($elementModel, $row); // If new, check if the element's db table is used by other tables and if so add the element to each of those tables' groups if ($new) { $this->addElementToOtherDbTables($elementModel, $row); } if (!$elementModel->onSave($data)) { $this->setError(FText::_('COM_FABRIK_ERROR_SAVING_ELEMENT_PLUGIN_OPTIONS')); return false; } } parent::cleanCache('com_fabrik'); return $return; /** * used for prefab * return $elementModel; */ }
/** * Helper function to get an array of data from the checkbox joined db table. * Used for working out the filter sql and filter dropdown contents * * @param string $groupBy field name to key the results on - avoids duplicates * @param string $condition if supplied then filters the list (must then supply $where and $value) * @param string $value if supplied then filters the list (must then supply $where and $condtion) * @param string $where if supplied then filters the list (must then supply $value and $condtion) * @param int $offset query offset - default 0 * @param int $limit query limit - default 0 * * @return array rows */ protected function checkboxRows($groupBy = null, $condition = null, $value = null, $where = null, $offset = 0, $limit = 0) { $params = $this->getParams(); $db = $this->getDb(); $query = $db->getQuery(true); $join = $this->getJoinModel()->getJoin(); $jointable = $db->quoteName($join->table_join); $shortName = $db->quoteName($this->getElement()->name); if (is_null($groupBy)) { $groupBy = 'value'; } $to = $params->get('join_db_name'); $key = $db->quoteName($to . '.' . $params->get('join_key_column')); $label = $db->quoteName($to . '.' . $this->getLabelParamVal()); $v = $jointable . '.' . $shortName; $query->select($jointable . '.parent_id, ' . $v . ' AS value, ' . $label . ' AS text')->from($jointable)->join('LEFT', $to . ' ON ' . $key . ' = ' . $jointable . '.' . $shortName); if (!is_null($condition) && !is_null($value)) { if (is_null($where)) { $where = $label; } $query->where($where . ' ' . $condition . ' ' . $value); } $db->setQuery($query, $offset, $limit); $groupBy = FabrikString::shortColName($groupBy); $rows = $db->loadObjectList($groupBy); return $rows; }
/** * Compacts the ordering sequence of the selected records * * @param string $colid column name to order on * @param string $where additional where query to limit ordering to a particular subset of records * * @since 3.0.5 * * @return bool */ public function reorder($colid, $where = '') { $elementModel = $this->getFormModel()->getElement($colid, true); $asfields = array(); $fields = array(); $elementModel->getAsField_html($asfields, $fields); $col = $asfields[0]; $field = explode("AS", $col); $field = array_shift($field); $db = $this->getDb(); $k = $this->getTable()->db_primary_key; $shortKey = FabrikString::shortColName($k); $tbl = $this->getTable()->db_table_name; // Get the primary keys and ordering values for the selection. $query = $db->getQuery(true); $query->select($k . ' AS id, ' . $field . ' AS ordering'); $query->from($tbl); $query->where($field . ' >= 0'); $query->order($field); // Setup the extra where and ordering clause data. if ($where) { $query->where($where); } $db->setQuery($query); $rows = $db->loadObjectList(); // Compact the ordering values. foreach ($rows as $i => $row) { // Only update rows that are necessary. if ($row->ordering != $i + 1) { // Update the row ordering field. $query = $db->getQuery(true); $query->update($tbl); $query->set($field . ' = ' . ($i + 1)); $query->where($k . ' = ' . $db->quote($row->id)); $db->setQuery($query); $db->execute(); } } return true; }
/** * A group has been set to be repeatable but is not part of a join * so we want to: * Create a new db table for the groups elements ( + check if its not already there) * * @param array &$data jform data * * @return bool */ public function makeJoinedGroup(&$data) { $groupModel = JModelLegacy::getInstance('Group', 'FabrikFEModel'); $groupModel->setId($data['id']); $listModel = $groupModel->getListModel(); $db = $listModel->getDb(); $list = $listModel->getTable(); $elements = (array) $groupModel->getMyElements(); $names = array(); $fields = $listModel->getDBFields(null, 'Field'); $names['id'] = "id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY"; $names['parent_id'] = "parent_id INT(11)"; foreach ($elements as $element) { $fname = $element->getElement()->name; /** * if we are making a repeat group from the primary group then we don't want to * overwrite the repeat group tables id definition with that of the main tables */ if (!array_key_exists($fname, $names)) { $str = FabrikString::safeColName($fname); $field = FArrayHelper::getValue($fields, $fname); if (is_object($field)) { $str .= " " . $field->Type . " "; if ($field->Null == 'NO') { $str .= "NOT NULL "; } $names[$fname] = $str; } else { $names[$fname] = $db->quoteName($fname) . ' ' . $element->getFieldDescription(); } } } $db->setQuery("show tables"); $newTableName = $list->db_table_name . '_' . $data['id'] . '_repeat'; $existingTables = $db->loadColumn(); if (!in_array($newTableName, $existingTables)) { // No existing repeat group table found so lets create it $query = "CREATE TABLE IF NOT EXISTS " . $db->quoteName($newTableName) . " (" . implode(",", $names) . ")"; $db->setQuery($query); $db->execute(); // Create id and parent_id elements $listModel->makeIdElement($data['id']); $listModel->makeFkElement($data['id']); } else { if (trim($list->db_table_name) == '') { // New group not attached to a form $this->setError(FText::_('COM_FABRIK_GROUP_CANT_MAKE_JOIN_NO_DB_TABLE')); return false; } // Repeat table already created - lets check its structure matches the group elements $db->setQuery("DESCRIBE " . $db->quoteName($newTableName)); $existingFields = $db->loadObjectList('Field'); $newFields = array_diff(array_keys($names), array_keys($existingFields)); if (!empty($newFields)) { $lastField = array_pop($existingFields); $lastField = $lastField->Field; foreach ($newFields as $newField) { $info = $names[$newField]; $db->setQuery("ALTER TABLE " . $db->quoteName($newTableName) . " ADD COLUMN {$info} AFTER {$lastField}"); $db->execute(); } } } // Create the join as well $jdata = array('list_id' => $list->id, 'element_id' => 0, 'join_from_table' => $list->db_table_name, 'table_join' => $newTableName, 'table_key' => FabrikString::shortColName($list->db_primary_key), 'table_join_key' => 'parent_id', 'join_type' => 'left', 'group_id' => $data['id']); // Load the matching join if found. $join = $this->getTable('join'); $join->load($jdata); $opts = new stdClass(); $opts->type = 'group'; $jdata['params'] = json_encode($opts); $join->bind($jdata); // Update or save a new join $join->store(); $data['is_join'] = 1; $listModel->addIndex($newTableName . '___parent_id', 'parent_fk', 'INDEX', ''); return true; }
/** * Do the plugin action * * @param array &$data selected data * @param object &$listModel list model * * @return number of records updated */ public function process(&$data, &$listModel) { $params = $this->getParams(); $gcal_url = $params->get('gcal_sync_gcal_url'); $matches = array(); /* This matches a standard GCal URL, found under the Google "Calender Details" tab, using the XML button. * It should match any form, for public or private ... * http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/public/basic * http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/private-3081eca2b0asdfasdf8f106ea6f63343056/basic */ if (preg_match('#feeds/(.*?)/(\\w+-\\w+|\\w+)/(\\w+)#', $gcal_url, $matches)) { // Grab the bits of the URL we need for the Zend framework call $gcal_user = $matches[1]; $gcal_visibility = $matches[2]; $gcal_projection = $matches[3]; $gcal_email = urldecode($gcal_user); // Grab the table model and find table name and PK $table = $listModel->getTable(); $table_name = $table->db_table_name; /* For now, we have to read the table ourselves. We can't rely on the $data passed to us * because it can be filtered, and we need to see all records to know if the GCal events * already exist in the table */ $mydata = array(); $db = FabrikWorker::getDbo(); $query = $db->getQuery(true); $query->select('*')->from($table_name); $db->setQuery($query); $mydata[0] = $db->loadObjectList(); // Grab all the field names to use $gcal_label_element_long = $params->get('gcal_sync_label_element'); $gcal_label_element = FabrikString::shortColName($gcal_label_element_long); $gcal_desc_element_long = $params->get('gcal_sync_desc_element'); $gcal_desc_element = FabrikString::shortColName($gcal_desc_element_long); $gcal_start_date_element_long = $params->get('gcal_sync_startdate_element'); $gcal_start_date_element = FabrikString::shortColName($gcal_start_date_element_long); $gcal_end_date_element_long = $params->get('gcal_sync_enddate_element'); $gcal_end_date_element = FabrikString::shortColName($gcal_end_date_element_long); $gcal_id_element_long = $params->get('gcal_sync_id_element'); $gcal_id_element = FabrikString::shortColName($gcal_id_element_long); $gcal_userid_element_long = $params->get('gcal_sync_userid_element'); $gcal_userid_element = FabrikString::shortColName($gcal_userid_element_long); // Sanity check, make sure required elements have been specified if (empty($gcal_label_element_long) || empty($gcal_start_date_element_long) || empty($gcal_end_date_element_long) || empty($gcal_id_element_long)) { return; } // If they selected a User ID element to use, see if we can find a J! user with matching email to this feed's owner $our_userid = 0; if ($gcal_userid_element_long) { $query = $db->getQuery(true); $query->select('id')->from('#__users')->whre('email = ' . $db->quote('$gcal_email')); $db->setQuery($query); $our_userid = $db->loadResult(); // Better make sure it's not NULL, in case underlying column is NOT NULL if (empty($our_userid)) { $our_userid = 0; } } // Include the Zend stuff $path = JPATH_SITE . '/libraries'; set_include_path(get_include_path() . PATH_SEPARATOR . $path); $path = get_include_path(); require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); /* Won't need these loaded until we add sync'ing events back to Google * Zend_Loader::loadClass('Zend_Gdata_AuthSub'); * Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); */ Zend_Loader::loadClass('Zend_Gdata_Calendar'); // See if they want to sync to gcal, and provided a login $gcal_sync_upload = $params->get('gcal_sync_upload_events', 'from'); if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); $email = $params->get('gcal_sync_login', ''); $passwd = $params->get('gcal_sync_passwd', ''); try { $client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl'); } catch (Zend_Gdata_App_CaptchaRequiredException $cre) { echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "\n"; echo 'Token ID: ' . $cre->getCaptchaToken() . "\n"; return; } catch (Zend_Gdata_App_AuthException $ae) { echo 'Problem authenticating: ' . $ae->exception() . "\n"; return; } $gdataCal = new Zend_Gdata_Calendar($client); } else { $gdataCal = new Zend_Gdata_Calendar(); } // Set up and execute the call to grab the feed from google $query = $gdataCal->newEventQuery(); $query->setUser($gcal_user); $query->setVisibility($gcal_visibility); $query->setProjection($gcal_projection); $eventFeed = $gdataCal->getCalendarEventFeed($query); // Build an array of the events from the feed, indexed by the Google ID $event_ids = array(); foreach ($eventFeed as $key => $event) { $short_id = $this->_getGcalShortId($event->id->text); $gcal_event_ids[$short_id] = $eventFeed[$key]; } /* Run through our table data, and build an array of our events indexed by the Google ID * (of course not all events may have a Google ID) */ $our_event_ids = array(); $our_upload_ids = array(); foreach ($mydata as $gkey => $group) { if (is_array($group)) { foreach ($group as $rkey => $row) { if ($row->{$gcal_id_element}) { $our_event_ids[$row->{$gcal_id_element}] = $mydata[$gkey][$rkey]; } else { $our_upload_ids[] = $mydata[$gkey][$rkey]; } } } } // Now go through the google events id's, and process the ones which aren't in our table. $our_event_adds = array(); foreach ($gcal_event_ids as $id => $event) { if (!array_key_exists($id, $our_event_ids)) { // we don't have the ID, so add the event to our table $row = array(); $row[$gcal_start_date_element] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->startTime)); $row[$gcal_end_date_element] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->endTime)); $row[$gcal_label_element] = $event->title->text; $row[$gcal_desc_element] = $event->content->text; $row[$gcal_id_element] = $id; if ($gcal_userid_element_long) { $row[$gcal_userid_element] = $our_userid; } $listModel->storeRow($row, 0); } } // If upload syncing (from us to gcal) is enabled ... if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { // Grab the tzOffset. Note that gcal want +/-XX (like -06) // but J! gives us +/-X (like -6) so we sprintf it to the right format $config = JFactory::getConfig(); $tzOffset = (int) $config->getValue('config.offset'); $tzOffset = sprintf('%+03d', $tzOffset); // Loop thru the array we built earlier of events we have that aren't in gcal foreach ($our_upload_ids as $id => $event) { // Skip if a userid element is specified, and doesn't match the owner of this gcal if ($gcal_userid_element_long) { if ($event->{$gcal_userid_element} != $our_userid) { continue; } } // Now start building the gcal event structure $newEvent = $gdataCal->newEventEntry(); $newEvent->title = $gdataCal->newTitle($event->{$gcal_label_element}); if ($gcal_desc_element_long) { $newEvent->content = $gdataCal->newContent($event->{$gcal_desc_element}); } else { $newEvent->content = $gdataCal->newContent($event->{$gcal_label_element}); } $when = $gdataCal->newWhen(); // Grab the start date, apply the tx offset, and format it for gcal $start_date = JFactory::getDate($event->{$gcal_start_date_element}); $start_date->setOffset($tzOffset); $start_fdate = $start_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $start_fdate); $when->startTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; /* We have to provide an end date for gcal, so if we don't have one, * default it to start date + 1 hour */ if ($event->{$gcal_end_date_element} == '0000-00-00 00:00:00') { $startstamp = strtotime($event->{$gcal_start_date_element}); $endstamp = $startstamp + 60 * 60; $event->{$gcal_end_date_element} = strftime('%Y-%m-%d %H:%M:%S', $endstamp); } // Grab the end date, apply the tx offset, and format it for gcal $end_date = JFactory::getDate($event->{$gcal_end_date_element}); $end_date->setOffset($tzOffset); $end_fdate = $end_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $end_fdate); $when->endTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; $newEvent->when = array($when); // Fire off the insertEvent to gcal, catch any errors try { $retEvent = $gdataCal->insertEvent($newEvent); } catch (Zend_Gdata_App_HttpException $he) { $errStr = 'Problem adding event: ' . $he->getRawResponseBody() . "\n"; continue; } /* So, insertEvent worked, grab the gcal ID from the returned event data, * and update our event record with the short version of the ID */ $gcal_id = $this->_getGcalShortId($retEvent->id->text); $our_id = $event->id; $query = $db->getQuery(true); $query->update($table_name)->set($gcal_id_element . ' = ' . $db->quote($gcal_id))->where('id = ' . $db->quote($our_id)); $db->setQuery($query); $db->query(); } } } }
/** * do the plugin action * */ function process(&$data, &$listModel) { $params =& $this->getParams(); // grab the table model and find table name and PK $table =& $listModel->getTable(); $table_name = $table->db_table_name; $primary_key = $table->db_primary_key; $primary_key_element = FabrikString::shortColName($table->db_primary_key); // for now, we have to read the table ourselves. We can't rely on the $data passed to us // because it can be arbitrarily filtered according to who happened to hit the page when cron // needed to run. $mydata = array(); $db = FabrikWorker::getDbo(); $db->setQuery("SELECT * FROM {$table_name}"); $mydata[0] = $db->loadObjectList(); // grab all the params, like GMaps key, field names to use, etc $geocode_gmap_key = $params->get('geocode_gmap_key'); $geocode_is_empty = $params->get('geocode_is_empty'); $geocode_zoom_level = $params->get('geocode_zoom_level', '4'); $geocode_map_element_long = $params->get('geocode_map_element'); $geocode_map_element = FabrikString::shortColName($geocode_map_element_long); $geocode_addr1_element_long = $params->get('geocode_addr1_element'); $geocode_addr1_element = $geocode_addr1_element_long ? FabrikString::shortColName($geocode_addr1_element_long) : ''; $geocode_addr2_element_long = $params->get('geocode_addr2_element'); $geocode_addr2_element = $geocode_addr2_element_long ? FabrikString::shortColName($geocode_addr2_element_long) : ''; $geocode_city_element_long = $params->get('geocode_city_element'); $geocode_city_element = $geocode_city_element_long ? FabrikString::shortColName($geocode_city_element_long) : ''; $geocode_state_element_long = $params->get('geocode_state_element'); $geocode_state_element = $geocode_state_element_long ? FabrikString::shortColName($geocode_state_element_long) : ''; $geocode_zip_element_long = $params->get('geocode_zip_element'); $geocode_zip_element = $geocode_zip_element_long ? FabrikString::shortColName($geocode_zip_element_long) : ''; $geocode_country_element_long = $params->get('geocode_country_userid_element'); $geocode_country_element = $geocode_country_element_long ? FabrikString::shortColName($geocode_country_element_long) : ''; // sanity check, make sure required elements have been specified if (empty($geocode_gmap_key)) { JError::raiseNotice(500, 'No google maps key specified'); return; } $gmap = new GMaps($geocode_gmap_key); // run through our table data $total_encoded = 0; foreach ($mydata as $gkey => $group) { if (is_array($group)) { foreach ($group as $rkey => $row) { // see if the map element is considered empty if (empty($row->{$geocode_map_element}) || $row->{$geocode_map_element} == $geocode_is_empty) { // it's empty, so lets try and geocode. // first, construct the address // we'll build an array of address components, which we'll explode into a string later $a_full_addr = array(); // for each address component element, see if one is specific in the params, // if so, see if it has a value in this row // if so, add it to the address array. if ($geocode_addr1_element) { if ($row->{$geocode_addr1_element}) { $a_full_addr[] = $row->{$geocode_addr1_element}; } } if ($geocode_addr2_element) { if ($row->{$geocode_addr2_element}) { $a_full_addr[] = $row->{$geocode_addr2_element}; } } if ($geocode_city_element) { if ($row->{$geocode_city_element}) { $a_full_addr[] = $row->{$geocode_city_element}; } } if ($geocode_state_element) { if ($row->{$geocode_state_element}) { $a_full_addr[] = $row->{$geocode_state_element}; } } if ($geocode_zip_element) { if ($row->{$geocode_zip_element}) { $a_full_addr[] = $row->{$geocode_zip_element}; } } if ($geocode_country_element) { if ($row->{$geocode_country_element}) { $a_full_addr[] = $row->{$geocode_zip_element}; } } // now explode the address into a string $full_addr = implode(',', $a_full_addr); // Did we actually get an address? if (!empty($full_addr)) { // OK! Lets try and geocode it ... if ($gmap->getInfoLocation($full_addr)) { echo 'found '; $lat = $gmap->getLatitude(); $long = $gmap->getLongitude(); if (!empty($lat) && !empty($long)) { $map_value = "({$lat},{$long}):{$geocode_zoom_level}"; $db->setQuery("\r\n\t\t\t\t\t\t\t\t\t\tUPDATE {$table_name}\r\n\t\t\t\t\t\t\t\t\t\tSET {$geocode_map_element} = '{$map_value}'\r\n\t\t\t\t\t\t\t\t\t\tWHERE {$primary_key} = '{$row->{$primary_key_element}}'\r\n\t\t\t\t\t\t\t\t\t"); $db->query(); $total_encoded++; } } } } } } } return $total_encoded; }
/** * process the data to the database * * @return null */ 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[FabrikString::shortColName($item->db_primary_key)] = $insertId; $this->_fullFormData[$tmpKey] = $insertId; //need for things like the redirect plugin $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 $aPreProcessedJoin) { if (!array_key_exists('join', $aPreProcessedJoin)) { continue; } $oJoin = $aPreProcessedJoin['join']; if (array_key_exists('Copy', $this->_formData)) { $this->_rowId = ''; $this->_formData['join'][$oJoin->id][$oJoin->table_join . '___' . $oJoin->table_key] = ''; $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'); // 3.0 test on repeatElement param type if (is_string($oJoin->params)) { $oJoin->params = json_decode($oJoin->params); } $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 = $pluginManager->getPlugIn('internalid', 'element'); $idElementModel->getElement()->name = 'id'; $idElementModel->getElement()->group_id = $elementModel->getGroup()->getGroup()->id; $idElementModel->_group = $elementModel->getGroup(); $idElementModel->_group = $elementModel->_group; $idElementModel->_aFullNames['id1_1__1_'] = $oJoin->table_join . '___id'; $parentElement = $pluginManager->getPlugIn('field', 'element'); $parentElement->getElement()->name = 'parent_id'; $parentElement->getElement()->group_id = $elementModel->getGroup()->getGroup()->id; $parentElement->_group = $elementModel->getGroup(); $parentElement->_group = $elementModel->_group; $parentElement->_aFullNames['parent_id1_1__1_'] = $oJoin->table_join . '___parent_id'; $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(); $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)) { //$$$rob get the join tables ful primary key $joinDb->setQuery("DESCRIBE {$oJoin->table_join}"); $oJoinPk = $oJoin->table_join . '___'; $cols = $joinDb->loadObjectList(); foreach ($cols as $col) { if ($col->Key == 'PRI') { $oJoinPk .= $col->Field; break; } } $fullforeginKey = $oJoin->table_join . '___' . $oJoin->table_join_key; $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 = is_array($data[$n]) && array_key_exists($c, $data[$n]) ? $data[$n][$c] : ''; $repData[$element->name] = $v; //store any params set in the individual plug-in (see fabrikfileupload::processUpload()->crop() if ($elementModel->isJoin()) { $repData['params'] = JArrayHelper::getValue($repeatParams, $c); } } // $$$ rob didn't work for 2nd joined data set //$repData[$oJoin->table_join_key] = $insertId; $repData[$oJoin->table_join_key] = JArrayHelper::getValue($joinKeys, $oJoin->join_from_table . '.' . $oJoin->table_key, $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 { $query->delete($oJoin->table_join)->where("!({$item->db_primary_key} IN (" . implode(',', $aUpdatedRecordIds) . ")) 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. 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; $this->_formData[$fk . '_raw'] = $pkVal; // because storeRow takes _raw if the key exists, which it does //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(); }
/** * a group has been set to be repeatable but is not part of a join * so we want to: * Create a new db table for the groups elements ( + check if its not already there) * * @param unknown_type $data */ public function makeJoinedGroup(&$data) { //JModel::addIncludePath(COM_FABRIK_FRONTEND.DS.'models'); $groupModel = JModel::getInstance('Group', 'FabrikFEModel'); $groupModel->setId($data['id']); $listModel = $groupModel->getListModel(); $pluginManager = $listModel->getPluginManager(); $db = $listModel->getDb(); $list = $listModel->getTable(); $elements = (array)$groupModel->getMyElements(); $names = array(); $fields = $listModel->getDBFields(null, 'Field'); $names['id'] = "id INT( 6 ) NOT NULL AUTO_INCREMENT PRIMARY KEY"; $names['parent_id'] = "parent_id INT(6)"; foreach ($elements as $element) { $fname = $element->getElement()->name; // if we are making a repeat group from the primary group then we dont want to // overwrite the repeat group tables id definition with that of the main tables if (!array_key_exists($fname, $names)) { $str = FabrikString::safeColName($fname); $field = JArrayHelper::getValue($fields, $fname); if (is_object($field)) { $str .= " ".$field->Type." "; if ($field->Null == 'NO') { $str .= "NOT NULL "; } $names[$fname] = $str; } else { $names[$fname] = $db->nameQuote($fname).' '.$element->getFieldDescription(); } } } $db->setQuery("show tables"); $newTableName = $list->db_table_name.'_'.$data['id'].'_repeat'; $existingTables = $db->loadResultArray(); if (!in_array($newTableName, $existingTables)) { // no existing repeat group table found so lets create it $query = "CREATE TABLE IF NOT EXISTS ".$db->nameQuote($newTableName)." (".implode(",", $names).")"; $db->setQuery($query); if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg()); } //create id and parent_id elements $listModel->makeIdElement($data['id']); $listModel->makeFkElement($data['id']); // create the join as well //create fabrik join $data = array('list_id' => $list->id, 'element_id' => 0, 'join_from_table' => $list->db_table_name, 'table_join' => $newTableName, 'table_key' => FabrikString::shortColName($list->db_primary_key), 'table_join_key' => 'parent_id', 'join_type' => 'left', 'group_id' => $data['id'] ); $opts = new stdClass(); $opts->type = 'group'; $data['params'] = json_encode($opts); $join = $this->getTable('join'); $join->bind($data); $join->store(); } else { if (trim($list->db_table_name) == '') { //new group not attached to a form $this->setError(JText::_('COM_FABRIK_GROUP_CANT_MAKE_JOIN_NO_DB_TABLE')); return false; } $newTableName = $db->nameQuote($newTableName); //repeat table already created - lets check its structure matches the group elements $db->setQuery("DESCRIBE $newTableName"); $existingFields = $db->loadObjectList('Field'); $newFields = array_diff(array_keys($names), array_keys($existingFields)); if (!empty($newFields)) { $lastfield = array_pop($existingFields); $lastfield = $lastfield->Field; foreach ($newFields as $newField) { $info = $names[$newField]; $db->setQuery("ALTER TABLE $newTableName ADD COLUMN $info AFTER $lastfield"); if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg()); } } } } $data['is_join'] = 1; return true; }
/** * get the field name to use as the column that contains the join's label data * @param bol use step in element name * @return string join label column either returns concat statement or quotes `tablename`.`elementname` */ function getJoinLabelColumn($useStep = false) { if (!isset($this->joinLabelCols)) { $this->joinLabelCols = array(); } if (array_key_exists((int) $useStep, $this->joinLabelCols)) { return $this->joinLabelCols[$useStep]; } $params = $this->getParams(); $db = $this->getDb(); $join =& $this->getJoin(); if ($params->get('join_val_column_concat') != '' && JRequest::getVar('overide_join_val_column_concat') != 1) { $val = str_replace("{thistable}", $join->table_join_alias, $params->get('join_val_column_concat')); $w = new FabrikWorker(); $val = $w->parseMessageForPlaceHolder($val, array(), false); return "CONCAT(" . $val . ")"; } $label = FabrikString::shortColName($join->_params->get('join-label')); if ($label == '') { JError::raiseWarning(500, 'Could not find the join label for ' . $this->getElement()->name . ' try unlinking and saving it'); $label = $this->getElement()->name; } $joinTableName = $join->table_join_alias; $this->joinLabelCols[(int) $useStep] = $useStep ? $joinTableName . '___' . $label : $db->nameQuote($joinTableName) . '.' . $db->nameQuote($label); // "``.`$label`"; return $this->joinLabelCols[(int) $useStep]; }
/** * Insert data into a fabrik table * @return unknown */ function makeTableFromCSV() { $user = JFactory::getUser(); $dropData = JRequest::getInt('drop_data', 0, 'post'); $overWrite = JRequest::getInt('overwrite', 0, 'post'); $model = $this->getlistModel(); $model->_importingCSV = true; $model->getTable(); $formModel = $model->getFormModel(); if ($dropData) { $model->truncate(); } $item = $model->getTable(); $tableParams = $model->getParams(); $csvFullName = $tableParams->get('csvfullname', 0); $key = FabrikString::shortColName($item->db_primary_key); //get a list of exisitng primary key vals $db = $model->getDb(); $query = $db->getQuery(true); $query->select($item->db_primary_key)->from($item->db_table_name); $db->setQuery($query); $aExistingKeys = $db->loadResultArray(); $this->addedCount = 0; $updatedCount = 0; $joins = $this->getJoins(); // $$$ rob we are no longer removing the element joins from $joins // so lets see if any of $joins are table joins. $tableJoinsFound = false; for ($x = 0; $x < count($joins); $x++) { if ((int)$joins[$x]->list_id !== 0) { $tableJoinsFound = true; } } $joindata = array(); $defaultsToAdd = $this->defaultsToAdd(); foreach ($this->data as $data) { $aRow = array(); $pkVal = null; $i =0; foreach ($this->matchedHeadings as $headingKey => $heading) { switch ($csvFullName) { case 0: break; case 1: $heading = array_pop(explode(".", $heading)); break; case 2: break; } //test _raw key and use that if (substr($heading, strlen($heading)-4, strlen($heading)) == "_raw") { $pktestHeading = substr($heading, 0, strlen($heading)-4); } else { $pktestHeading = $heading; } //$$$rob isset($pkVal) because: It could be that you have two elements (short names) with the // same name (if trying to import joined data, in this case I'm //presuming that the master table's pkval is the first one you come to if ($pktestHeading == $key && !isset($pkVal)) { $pkVal = $data[$i]; } // $$$ hugh - removed 'else', as we need to include the PK val, in case it's not auto-inc // and import needs to preserve PK provided in CSV data //else { $aRow[str_replace('.', '___', $headingKey)] = $data[$i]; //} $i ++; } // $$$ rob add in per row default values for missing elements foreach ($defaultsToAdd as $k => $elementModel) { $aRow[$k] = $elementModel->getDefaultValue($aRow); $aRow[$k.'_raw'] = $aRow[$k]; } $model->getFormGroupElementData(); //take any _raw values and replace their real elements with their data foreach ($aRow as $k=>$val) { if (substr($k, strlen($k)-4, strlen($k)) == "_raw") { $noneraw = substr($k, 0, strlen($k)-4); if (array_key_exists($noneraw, $aRow)) { $aRow[$noneraw] = $val; unset($aRow[$k]); } } } if ($overWrite && in_array($pkVal, $aExistingKeys)) { $formModel->_rowId = $pkVal; $updatedCount ++; } else { $formModel->_rowId = 0; $this->addedCount ++; } // $$$ rob - if raw and none raw or just raw found then insert the raw data // into the none raw key. Otherwise if just importing raw data no data stored foreach ($aRow as $k=>$val) { if (substr($k, strlen($k)-4, strlen($k)) == "_raw") { $noneraw = substr($k, 0, strlen($k)-4); $aRow[$noneraw] = $val; unset($aRow[$k]); } } if (!$tableJoinsFound) { $formModel->_formData = $aRow; $model->getPluginManager()->runPlugins('onImportCSVRow', $model, 'list'); $formModel->processToDB(); } else { //merge multi line csv into one entry & defer till we've passed everything $joindata = $this->_fakeJoinData($joindata, $aRow, $pkVal, $formModel); } } if ($tableJoinsFound) { $this->insertJoinedData($joindata); } $elementsCreated = count($this->newHeadings); $this->updatedCount = $updatedCount; if ($elementsCreated == 0) { $msg = JText::sprintf("%s CSV records added and %s records updated", $this->addedCount, $updatedCount); } else { $msg = JText::sprintf("%s new elements added, %s CSV records added and %s records updated", $elementsCreated, $this->addedCount, $updatedCount); } return $msg; }
/** * Called from paypal at the end of the transaction * * @return void */ public function onIpn() { $config = JFactory::getConfig(); JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fabrik/tables'); $log = FabTable::getInstance('log', 'FabrikTable'); $log->referring_url = $_SERVER['REQUEST_URI']; $log->message_type = 'fabrik.ipn.start'; $log->message = json_encode($_REQUEST); $log->store(); // Lets try to load in the custom returned value so we can load up the form and its parameters $custom = JRequest::getVar('custom'); list($formid, $rowid, $ipn_value) = explode(":", $custom); // Pretty sure they are added but double add JModel::addIncludePath(COM_FABRIK_FRONTEND . '/models'); $formModel = JModel::getInstance('Form', 'FabrikFEModel'); $formModel->setId($formid); $listModel = $formModel->getlistModel(); $params = $formModel->getParams(); $table = $listModel->getTable(); $db = $listModel->getDb(); $query = $db->getQuery(true); /* $$$ hugh * @TODO shortColName won't handle joined data, need to fix this to use safeColName * (don't forget to change quoteName stuff later on as well) */ $renderOrder = JRequest::getInt('renderOrder'); $ipn_txn_field = (array) $params->get('paypal_ipn_txn_id_element', array()); $ipn_txn_field = FabrikString::shortColName($ipn_txn_field[$renderOrder]); $ipn_payment_field = (array) $params->get('paypal_ipn_payment_element', array()); $ipn_payment_field = FabrikString::shortColName($ipn_payment_field[$renderOrder]); $ipn_field = (array) $params->get('paypal_ipn_element', array()); $ipn_field = FabrikString::shortColName($ipn_field[$renderOrder]); $ipn_status_field = (array) $params->get('paypal_ipn_status_element', array()); $ipn_status_field = FabrikString::shortColName($ipn_status_field[$renderOrder]); $ipn_address_field = (array) $params->get('paypal_ipn_address_element', array()); $ipn_address_field = FabrikString::shortColName($ipn_address_field[$renderOrder]); $w = new FabrikWorker(); $ipn_value = str_replace('[', '{', $ipn_value); $ipn_value = str_replace(']', '}', $ipn_value); $ipn_value = $w->parseMessageForPlaceHolder($ipn_value, $_POST); $email_from = $admin_email = $config->get('mailfrom'); // Read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; foreach ($_POST as $key => $value) { $value = urlencode(stripslashes($value)); $req .= "&{$key}={$value}"; } // Post back to PayPal system to validate $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Host: www.paypal.com:443\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . JString::strlen($req) . "\r\n\r\n"; if ($_POST['test_ipn'] == 1) { $paypalurl = 'ssl://www.sandbox.paypal.com'; } else { $paypalurl = 'ssl://www.paypal.com'; } // Assign posted variables to local variables $item_name = JRequest::getVar('item_name'); $item_number = JRequest::getVar('item_number'); $payment_status = JRequest::getVar('payment_status'); $payment_amount = JRequest::getVar('mc_gross'); $payment_currency = JRequest::getVar('mc_currency'); $txn_id = JRequest::getVar('txn_id'); $txn_type = JRequest::getVar('txn_type'); $receiver_email = JRequest::getVar('receiver_email'); $payer_email = JRequest::getVar('payer_email'); $buyer_address = JRequest::getVar('address_status') . ' - ' . JRequest::getVar('address_street') . ' ' . JRequest::getVar('address_zip') . ' ' . JRequest::getVar('address_state') . ' ' . JRequest::getVar('address_city') . ' ' . JRequest::getVar('address_country_code'); $status = 'ok'; $err_msg = ''; if (empty($formid) || empty($rowid)) { $status = 'form.paypal.ipnfailure.custom_error'; $err_msg = "formid or rowid empty in custom: {$custom}"; } else { // @TODO implement a curl alternative as fsockopen is not always available $fp = fsockopen($paypalurl, 443, $errno, $errstr, 30); if (!$fp) { $status = 'form.paypal.ipnfailure.fsock_error'; $err_msg = "fsock error: {$errno};{$errstr}"; } else { fputs($fp, $header . $req); while (!feof($fp)) { $res = fgets($fp, 1024); /* paypal steps (from their docs): * check the payment_status is Completed * check that txn_id has not been previously processed * check that receiver_email is your Primary PayPal email * check that payment_amount/payment_currency are correct * process payment */ if (JString::strcmp($res, "VERIFIED") == 0) { // $$tom This block Paypal from updating the IPN field if the payment status evolves (e.g. from Pending to Completed) // $$$ hugh - added check of status, so only barf if there is a status field, and it is Completed for this txn_id if (!empty($ipn_txn_field) && !empty($ipn_status_field)) { $query->clear(); $query->select($ipn_status_field)->from($table->db_table_name)->where($db->quoteName($ipn_txn_field) . ' = ' . $db->quote($txn_id)); $db->setQuery($query); $txn_result = $db->loadResult(); if (!empty($txn_result)) { if ($txn_result == 'Completed') { if ($payment_status != 'Reversed' && $payment_status != 'Refunded') { $status = 'form.paypal.ipnfailure.txn_seen'; $err_msg = "transaction id already seen as Completed, new payment status makes no sense: {$txn_id}, {$payment_status}"; } } elseif ($txn_result == 'Reversed') { if ($payment_status != 'Canceled_Reversal') { $status = 'form.paypal.ipnfailure.txn_seen'; $err_msg = "transaction id already seen as Reversed, new payment status makes no sense: {$txn_id}, {$payment_status}"; } } } } if ($status == 'ok') { $set_list = array(); if (!empty($ipn_field)) { if (empty($ipn_value)) { $ipn_value = $txn_id; } $set_list[$ipn_field] = $ipn_value; } if (!empty($ipn_txn_field)) { $set_list[$ipn_txn_field] = $txn_id; } if (!empty($ipn_payment_field)) { $set_list[$ipn_payment_field] = $payment_amount; } if (!empty($ipn_status_field)) { $set_list[$ipn_status_field] = $payment_status; } if (!empty($ipn_address_field)) { $set_list[$ipn_address_field] = $buyer_address; } $ipn = $this->getIPNHandler($params, $renderOrder); if ($ipn !== false) { $request = $_REQUEST; $ipn_function = 'payment_status_' . $payment_status; if (method_exists($ipn, $ipn_function)) { $status = $ipn->{$ipn_function}($listModel, $request, $set_list, $err_msg); if ($status != 'ok') { break; } } $txn_type_function = "txn_type_" . $txn_type; if (method_exists($ipn, $txn_type_function)) { $status = $ipn->{$txn_type_function}($listModel, $request, $set_list, $err_msg); if ($status != 'ok') { break; } } } if (!empty($set_list)) { $set_array = array(); foreach ($set_list as $set_field => $set_value) { $set_value = $db->quote($set_value); $set_field = $db->quoteName($set_field); $set_array[] = "{$set_field} = {$set_value}"; } $query->clear(); $query->update($table->db_table_name)->set(implode(',', $set_array))->where($table->db_primary_key . ' = ' . $db->quote($rowid)); $db->setQuery($query); if (!$db->query()) { $status = 'form.paypal.ipnfailure.query_error'; $err_msg = 'sql query error: ' . $db->getErrorMsg(); } } } } elseif (JString::strcmp($res, "INVALID") == 0) { $status = 'form.paypal.ipnfailure.invalid'; $err_msg = 'paypal postback failed with INVALID'; } } fclose($fp); } } $receive_debug_emails = (array) $params->get('paypal_receive_debug_emails'); $receive_debug_emails = $receive_debug_emails[$renderOrder]; $send_default_email = (array) $params->get('paypal_send_default_email'); $send_default_email = $send_default_email[$renderOrder]; if ($status != 'ok') { foreach ($_POST as $key => $value) { $emailtext .= $key . " = " . $value . "\n\n"; } if ($receive_debug_emails == '1') { $subject = $config->get('sitename') . ": Error with PayPal IPN from Fabrik"; JUtility::sendMail($email_from, $email_from, $admin_email, $subject, $emailtext, false); } $log->message_type = $status; $log->message = $emailtext . "\n//////////////\n" . $res . "\n//////////////\n" . $req . "\n//////////////\n" . $err_msg; if ($send_default_email == '1') { $payer_emailtext = "There was an error processing your PayPal payment. The administrator of this site has been informed."; JUtility::sendMail($email_from, $email_from, $payer_email, $subject, $payer_emailtext, false); } } else { foreach ($_POST as $key => $value) { $emailtext .= $key . " = " . $value . "\n\n"; } if ($receive_debug_emails == '1') { $subject = $config->get('sitename') . ': IPN ' . $payment_status; JUtility::sendMail($email_from, $email_from, $admin_email, $subject, $emailtext, false); } $log->message_type = 'form.paypal.ipn.' . $payment_status; $query = $db->getQuery(); $log->message = $emailtext . "\n//////////////\n" . $res . "\n//////////////\n" . $req . "\n//////////////\n" . $query; if ($send_default_email == '1') { $payer_subject = "PayPal success"; $payer_emailtext = "Your PayPal payment was succesfully processed. The PayPal transaction id was {$txn_id}"; JUtility::sendMail($email_from, $email_from, $payer_email, $payer_subject, $payer_emailtext, false); } } $log->message .= "\n IPN custom function = {$ipn_function}"; $log->message .= "\n IPN custom transaction function = {$txn_type_function}"; $log->store(); jexit(); }
/** * internal function: add a key to the table * @param string primary key column name * @param bol is the column auto incrementing * @param string the primary keys column type (if autoincrement true then int(6) is always used as the type) */ private function addKey($fieldName, $autoIncrement, $type = "INT(6)") { $db = $this->getFEModel()->getDb(); $type = $autoIncrement != true ? $type : 'INT(6)'; //$table =& $this->getTable(); //$table->load($this->getState('list.id')); $tableName = $post['jform']['db_table_name'] != '' ? $post['jform']['db_table_name'] : $post['jform']['_database_name']; $tableName = preg_replace('#[^0-9a-zA-Z_]#', '_', $tableName); $tableName = FabrikString::safeColName($tableName); $fieldName = FabrikString::shortColName($fieldName); if ($fieldName === "") { return false; } $sql = "ALTER TABLE " . $tableName . " ADD PRIMARY KEY ({$fieldName})"; /* add a primary key */ $db->setQuery($sql); if (!$db->query()) { return JError::raiseWarning(500, $db->getErrorMsg()); } if ($autoIncrement) { $sql = "ALTER TABLE " . $tableName . " CHANGE {$fieldName} {$fieldName} {$type} NOT NULL AUTO_INCREMENT"; //add the autoinc $db->setQuery($sql); if (!$db->query()) { return JError::raiseError(500, 'add key: ' . $db->getErrorMsg()); } } }
/** * do the plugin action * */ function process(&$data, &$tableModel) { //jimport('joomla.mail.helper'); $params =& $this->getParams(); $app =& Jfactory::getApplication(); $gcal_url = $params->get('gcal_sync_gcal_url'); $matches = array(); // this matches a standard GCal URL, found under the Google "Calender Details" tab, using the XML button. // It should match any form, for public or private ... // http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/public/basic // http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/private-3081eca2b0asdfasdf8f106ea6f63343056/basic $gcal_url = str_replace('/basic', '/full', $gcal_url); $gcal_url = preg_replace('#/private-\\w+/#', '/private/', $gcal_url); if (preg_match('#feeds/(.*?)/(\\w+-\\w+|\\w+)/(\\w+)#', $gcal_url, $matches)) { // grab the bits of the URL we need for the Zend framework call $gcal_user = $matches[1]; $gcal_visibility = $matches[2]; $gcal_projection = $matches[3]; $gcal_email = urldecode($gcal_user); // grab the table model and find table name and PK $table =& $tableModel->getTable(); $table_name = $table->db_table_name; $primary_key = $table->db_primary_key; $primary_key_element_long = FabrikString::safeColNameToArrayKey($table->db_primary_key); // for now, we have to read the table ourselves. We can't rely on the $data passed to us // because it can be filtered, and we need to see all records to know if the GCal events // already exist in the table /* $mydata = array(); $db = JFactory::getDBO(); $db->setQuery("SELECT * FROM $table_name"); $mydata[0] = $db->loadObjectList(); */ $db = JFactory::getDBO(); $mydata =& $data; // grab all the field names to use $gcal_label_element_long = $params->get('gcal_sync_label_element'); $gcal_label_element = FabrikString::shortColName($gcal_label_element_long); $gcal_desc_element_long = $params->get('gcal_sync_desc_element'); $gcal_desc_element = FabrikString::shortColName($gcal_desc_element_long); $gcal_start_date_element_long = $params->get('gcal_sync_startdate_element'); $gcal_start_date_element = FabrikString::shortColName($gcal_start_date_element_long); $gcal_end_date_element_long = $params->get('gcal_sync_enddate_element'); $gcal_end_date_element = FabrikString::shortColName($gcal_end_date_element_long); $gcal_id_element_long = $params->get('gcal_sync_id_element'); $gcal_id_element = FabrikString::shortColName($gcal_id_element_long); $gcal_userid_element_long = $params->get('gcal_sync_userid_element'); $gcal_userid_element = FabrikString::shortColName($gcal_userid_element_long); // sanity check, make sure required elements have been specified if (empty($gcal_label_element_long) || empty($gcal_start_date_element_long) || empty($gcal_end_date_element_long) || empty($gcal_id_element_long)) { JError::raiseNotice(500, 'missing gcal data'); return; } // if they selected a User ID element to use, see if we can find a J! user with matching email to this feed's owner $our_userid = 0; if ($gcal_userid_element_long) { $db->setQuery("SELECT id FROM " . $db->nameQuote('#__users') . " WHERE " . $db->nameQUote('email') . " = " . $db->Quote($gcal_email)); $our_userid = $db->loadResult(); // better make sure it's not NULL, in case underlying column is NOT NULL if (empty($our_userid)) { $our_userid = 0; } } // include the Zend stuff $path = JPATH_SITE . DS . 'libraries'; set_include_path(get_include_path() . PATH_SEPARATOR . $path); $path = get_include_path(); require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Uri_Http'); // Won't need these loaded until we add sync'ing events back to Google //Zend_Loader::loadClass('Zend_Gdata_AuthSub'); //Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); // see if they want to sync to gcal, and provided a login $gcal_sync_upload = $params->get('gcal_sync_upload_events', 'from'); if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); $email = $params->get('gcal_sync_login', ''); $passwd = $params->get('gcal_sync_passwd', ''); try { $client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl'); } catch (Zend_Gdata_App_CaptchaRequiredException $cre) { echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "\n"; echo 'Token ID: ' . $cre->getCaptchaToken() . "\n"; return; } catch (Zend_Gdata_App_AuthException $ae) { echo 'Problem authenticating: ' . $ae->exception() . "\n"; return; } $gdataCal = new Zend_Gdata_calendar($client); } else { $gdataCal = new Zend_Gdata_calendar(); } // set up and execute the call to grab the feed from google $query = $gdataCal->newEventQuery(); $query->setUser($gcal_user); $query->setVisibility($gcal_visibility); $query->setProjection($gcal_projection); $eventFeed = $gdataCal->getCalendarEventFeed($query); // build an array of the events from the feed, indexed by the Google ID $event_ids = array(); foreach ($eventFeed as $key => $event) { $short_id = $this->_getGcalShortId($event->id->text); $gcal_event_ids[$short_id] =& $eventFeed[$key]; } // run through our table data, and build an array of our events indexed by the Google ID // (of course not all events may have a Google ID) $our_event_ids = array(); $our_upload_ids = array(); foreach ($mydata as $gkey => $group) { if (is_array($group)) { foreach ($group as $rkey => $row) { if ($row->{$gcal_id_element_long}) { $our_event_ids[$row->{$gcal_id_element_long}] =& $mydata[$gkey][$rkey]; } else { $our_upload_ids[] =& $mydata[$gkey][$rkey]; } } } } // now go through the google events id's, and process the ones which aren't in our table. $our_event_adds = array(); foreach ($gcal_event_ids as $id => $event) { if (!array_key_exists($id, $our_event_ids)) { // we don't have the ID, so add the event to our table $row = array(); $row[$gcal_start_date_element_long] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->startTime)); if ($gcal_end_date_element_long) { $row[$gcal_end_date_element_long] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->endTime)); } $row[$gcal_label_element_long] = $event->title->text; if ($gcal_desc_element_long) { $row[$gcal_desc_element_long] = $event->content->text; } $row[$gcal_id_element_long] = $id; if ($gcal_userid_element_long) { $row[$gcal_userid_element_long] = $our_userid; } $tableModel->storeRow($row, 0); } $our_event_adds[$id] = $row; } $app->enqueueMessage(count($our_event_adds) . ' events added '); // if upload syncing (from us to gcal) is enabled ... if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { // Grab the tzOffset. Note that gcal want +/-XX (like -06) // but J! gives us +/-X (like -6) so we sprintf it to the right format $config =& JFactory::getConfig(); $tzOffset = (int) $config->getValue('config.offset'); $tzOffset = sprintf('%+03d', $tzOffset); // loop thru the array we built earlier of events we have that aren't in gcal $uploadCount = 0; foreach ($our_upload_ids as $id => $event) { // skip if a userid element is specified, and doesn't match the owner of this gcal if ($gcal_userid_element_long) { if ($event->{$gcal_userid_element_long} != $our_userid) { continue; } } // now start building the gcal event structure $newEvent = $gdataCal->newEventEntry(); $newEvent->title = $gdataCal->newTitle($event->{$gcal_label_element_long}); if ($gcal_desc_element_long) { $newEvent->content = $gdataCal->newContent($event->{$gcal_desc_element_long}); } else { $newEvent->content = $gdataCal->newContent($event->{$gcal_label_element_long}); } $when = $gdataCal->newWhen(); // grab the start date, apply the tx offset, and format it for gcal $start_date = JFactory::getDate($event->{$gcal_start_date_element_long}); $start_date->setOffset($tzOffset); $start_fdate = $start_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $start_fdate); $when->startTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; // we have to provide an end date for gcal, so if we don't have one, // default it to start date + 1 hour if (empty($gcal_end_date_element_long) || empty($event->{$gcal_end_date_element_long}) || $event->{$gcal_end_date_element_long} == '0000-00-00 00:00:00') { $startstamp = strtotime($event->{$gcal_start_date_element_long}); $endstamp = $startstamp + 60 * 60; $event->{$gcal_end_date_element_long} = strftime('%Y-%m-%d %H:%M:%S', $endstamp); } // grab the end date, apply the tx offset, and format it for gcal $end_date = JFactory::getDate($event->{$gcal_end_date_element_long}); $end_date->setOffset($tzOffset); $end_fdate = $end_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $end_fdate); $when->endTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; $newEvent->when = array($when); // fire off the insertEvent to gcal, catch any errors try { $retEvent = $gdataCal->insertEvent($newEvent, $gcal_url); } catch (Zend_Gdata_App_HttpException $he) { $errStr = 'Problem adding event: ' . $he->getRawResponseBody() . "\n"; continue; } $uploadCount++; // insertEvent worked, so grab the gcal ID from the returned event data, // and update our event record with the short version of the ID $gcal_id = $this->_getGcalShortId($retEvent->id->text); $our_id = $event->__pk_val; $db->setQuery("\n\t\t\t\t\t\tUPDATE {$table_name}\n\t\t\t\t\t\tSET {$gcal_id_element} = " . $db->Quote($gcal_id) . "\n\t\t\t\t\t\tWHERE {$primary_key} = " . (int) $our_id); $db->query(); } $app->enqueueMessage($uploadCount . ' events uploaded to GCal'); } } else { JError::raiseNotice(500, 'Incorrect url'); } }
/** * get the headings for the csv file * @return array heading labels */ function getHeadings() { $table =& $this->model->getTable(); $params =& $this->model->getParams(); $hformat = $params->get('csvfullname'); $data =& $this->model->getData(); $headings = array(); $g =& current($data); if (empty($g)) { return $g; } $selectedFields = JRequest::getVar('fields'); $r =& current($g); $formModel =& $this->model->getFormModel(); $groups =& $formModel->getGroupsHiarachy(); $h = array(); if (!is_object($r)) { return new stdClass(); } $incRaw = JRequest::getVar('incraw', true); $incData = JRequest::getVar('inctabledata', true); $shortkey = FabrikString::shortColName($table->db_primary_key); foreach ($r as $heading => $value) { $found = false; foreach ($groups as $groupModel) { $elementModels =& $groupModel->getPublishedElements(); foreach ($elementModels as $elementModel) { $element =& $elementModel->getElement(); $fullname = $elementModel->getFullName(false, true, false); if ($fullname == $heading || $fullname . "_raw" == $heading) { $found = true; switch ($hformat) { default: case '0': $n = $element->name; break; case '1': $n = $elementModel->getFullName(false, false, false); break; case '2': $headingLabel = $elementModel->getParams()->get('alt_list_heading'); $n = trim($headingLabel) === '' ? $element->label : $headingLabel; break; } if ($fullname . "_raw" == $heading) { $n .= "_raw"; } if ($incData && substr($n, strlen($n) - 4, strlen($n)) !== '_raw') { if (!in_array($n, $h)) { //only add heading once $h[] = $n; } else { $h[] = $this->uniqueHeading($n, $h); } } if ($incRaw && substr($n, strlen($n) - 4, strlen($n)) == "_raw") { if (!in_array($n, $h)) { //only add heading once $h[] = $n; } else { $h[] = $this->uniqueHeading($n, $h); } } } } } if (!$found) { if (!(substr($heading, strlen($heading) - 4, strlen($heading)) == "_raw" && !$incRaw)) { //stop id getting added to tables when exported wiht fullelname key if ($hformat != 1 && $heading != $shortkey) { $h[] = $heading; } } } } if (JRequest::getVar('inccalcs') == 1) { array_unshift($h, JText::_('Calculation')); } $h = array_map(array($this, "_quote"), $h); return $h; }
/** * Get the headings for the csv file * * @return array heading labels */ public function getHeadings() { $input = $this->app->input; $w = new FabrikWorker(); $table = $this->model->getTable(); $params = $this->model->getParams(); $headingFormat = $params->get('csvfullname'); $data = $this->model->getData(); $g = current($data); if (empty($g)) { return $g; } $r = current($g); $formModel = $this->model->getFormModel(); $groups = $formModel->getGroupsHiarachy(); $h = array(); if (!is_object($r)) { return new stdClass(); } $incRaw = $input->get('incraw', true); $incData = $input->get('inctabledata', true); $shortKey = FabrikString::shortColName($table->db_primary_key); foreach ($r as $heading => $value) { $found = false; foreach ($groups as $groupModel) { $elementModels = $groupModel->getPublishedElements(); foreach ($elementModels as $elementModel) { $element = $elementModel->getElement(); $fullName = $elementModel->getFullName(true, false); if ($fullName == $heading || $fullName . '_raw' == $heading) { $found = true; switch ($headingFormat) { default: case '0': $n = $element->name; break; case '1': $n = $elementModel->getFullName(false, false); break; case '2': $n = $elementModel->getListHeading(); break; } /** * $$$ hugh - added next line as special case for a client, do not remove! * (used in conjunction with "Custom QS" option, to allow variable header labels */ $n = $w->parseMessageForPlaceHolder($n, array()); if ($fullName . '_raw' == $heading) { $n .= '_raw'; } if ($incData && JString::substr($n, JString::strlen($n) - 4, JString::strlen($n)) !== '_raw') { if (!in_array($n, $h)) { // Only add heading once $h[] = $n; } else { $h[] = $this->uniqueHeading($n, $h); } } if ($incRaw && JString::substr($n, JString::strlen($n) - 4, strlen($n)) == '_raw') { if (!in_array($n, $h)) { // Only add heading once $h[] = $n; } else { $h[] = $this->uniqueHeading($n, $h); } } } } } if (!$found) { if (!(JString::substr($heading, JString::strlen($heading) - 4, JString::strlen($heading)) == '_raw' && !$incRaw)) { // Stop id getting added to tables when exported with full element name key if ($headingFormat != 1 && $heading != $shortKey) { $h[] = $heading; } } } } if ($input->get('inccalcs') == 1) { array_unshift($h, FText::_('Calculation')); } $h = array_map(array($this, "quote"), $h); return $h; }
/** * drop all indexes for a give element name * required when encrypting text fileds whcih have a key on them , as blobs cant have keys * @param string $field * @param string $table */ public function dropColumnNameIndex($field, $table = '') { $db = $this->getDb(); $table = $table == '' ? $this->getTable()->db_table_name : $table; $field = FabrikString::shortColName($field); if ($field == '') { return; } $db->setQuery("SHOW INDEX FROM " . $db->nameQuote($table) . ' WHERE Column_name = ' . $db->Quote($field)); $dbIndexes = $db->loadObjectList(); foreach ($dbIndexes as $index) { $db->setQuery(" ALTER TABLE " . $db->nameQuote($table) . " DROP INDEX " . $db->nameQuote($index->Key_name)); $db->query(); } }
/** * Internal function: add a key to the table * * @param string $fieldName primary key column name * @param bool $autoIncrement is the column auto incrementing * @param string $type the primary keys column type (if autoincrement true then int(6) is always used as * the type) * * @return mixed false / JError */ private function addKey($fieldName, $autoIncrement, $type = "INT(6)") { $db = $this->getFEModel()->getDb(); $input = $this->app->input; $type = $autoIncrement != true ? $type : 'INT(6)'; $jForm = $input->get('jform', array(), 'array'); $tableName = $jForm['db_table_name'] != '' ? $jForm['db_table_name'] : $jForm['_database_name']; $tableName = preg_replace('#[^0-9a-zA-Z_]#', '_', $tableName); $tableName = FabrikString::safeColName($tableName); $fieldName = FabrikString::shortColName($fieldName); if ($fieldName === '') { return false; } $fieldName = $db->qn($fieldName); $sql = 'ALTER TABLE ' . $tableName . ' ADD PRIMARY KEY (' . $fieldName . ')'; // Add a primary key $db->setQuery($sql); $db->execute(); if ($autoIncrement) { // Add the autoinc $sql = 'ALTER TABLE ' . $tableName . ' CHANGE ' . $fieldName . ' ' . $fieldName . ' ' . $type . ' NOT NULL AUTO_INCREMENT'; $db->setQuery($sql); $db->execute(); } return true; }
/** * Insert data into a Fabrik list * * @return null */ public function insertData() { $user = JFactory::getUser(); $app = JFactory::getApplication(); $jform = $app->input->get('jform', array(), 'array'); $dropData = (int) JArrayHelper::getValue($jform, 'drop_data', 0); $overWrite = (int) JArrayHelper::getValue($jform, 'overwrite', 0); $model = $this->getlistModel(); $model->importingCSV = true; $item = $model->getTable(); $formModel = $model->getFormModel(); // $$$ rob 27/17/212 we need to reset the form as it was first generated before its elements were created. $formModel->reset(); if ($dropData) { $model->truncate(); } $item = $model->getTable(); $tableParams = $model->getParams(); $csvFullName = $tableParams->get('csvfullname', 0); $key = FabrikString::shortColName($item->db_primary_key); // Get a list of exisitng primary key vals $db = $model->getDb(); $query = $db->getQuery(true); $query->select($item->db_primary_key)->from($item->db_table_name); $db->setQuery($query); $aExistingKeys = $db->loadColumn(); $this->addedCount = 0; $updatedCount = 0; // $$$ rob we are no longer removing the element joins from $joins // so lets see if any of $joins are table joins. $tableJoinsFound = $this->tableJoinsFound(); $joindata = array(); $defaultsToAdd = $this->defaultsToAdd(); foreach ($this->data as $data) { $aRow = array(); $pkVal = null; $i = 0; foreach ($this->matchedHeadings as $headingKey => $heading) { switch ($csvFullName) { case 0: break; case 1: $heading = explode('.', $heading); $heading = array_pop($heading); break; case 2: break; } // Test _raw key and use that if (JString::substr($heading, JString::strlen($heading) - 4, JString::strlen($heading)) == '_raw') { $pktestHeading = JString::substr($heading, 0, JString::strlen($heading) - 4); } else { $pktestHeading = $heading; } /* * $$$rob isset($pkVal) because: It could be that you have two elements (short names) with the * same name (if trying to import joined data, in this case I'm * presuming that the master table's pkval is the first one you come to */ if ($pktestHeading == $key && !isset($pkVal)) { $pkVal = $data[$i]; } $aRow[str_replace('.', '___', $headingKey)] = $data[$i]; $i++; } $this->addDefaults($aRow); $model->getFormGroupElementData(); $this->setRawDataAsPriority($aRow); if ($overWrite && in_array($pkVal, $aExistingKeys)) { $formModel->rowId = $pkVal; $updatedCount++; $model->csvOverwriting = true; } else { // If not overwriting ensusre the any existing PK's are removed and the form rowId set to '' $pk = FabrikString::safeColNameToArrayKey($item->db_primary_key); $rawPk = $pk . '_raw'; unset($aRow[$pk]); unset($aRow[$rawPk]); $formModel->rowId = ''; $formModel->setInsertId(''); $this->addedCount++; $model->csvOverwriting = false; } // $$$ rob - if raw and none raw or just raw found then insert the raw data // into the none raw key. Otherwise if just importing raw data no data stored foreach ($aRow as $k => $val) { if (JString::substr($k, JString::strlen($k) - 4, JString::strlen($k)) == '_raw') { $noneraw = JString::substr($k, 0, strlen($k) - 4); $aRow[$noneraw] = $val; } } if (!$tableJoinsFound) { $formModel->formData = $formModel->formDataWithTableName = $aRow; if (!in_array(false, FabrikWorker::getPluginManager()->runPlugins('onImportCSVRow', $model, 'list'))) { $rowid = $formModel->processToDB(); FabrikWorker::getPluginManager()->runPlugins('onAfterImportCSVRow', $model, 'list'); } } else { // Merge multi line csv into one entry & defer till we've passed everything $joindata = $this->_fakeJoinData($joindata, $aRow, $pkVal, $formModel); } } if ($tableJoinsFound) { $this->insertJoinedData($joindata); } $this->removeCSVFile(); $this->updatedCount = $updatedCount; }