From cc624c5ddb3f9bc3858409c6985e69ad014d7ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Thu, 3 Oct 2019 14:23:00 +0530 Subject: [PATCH] Task #199 feat: Save process optimisation --- administrator/models/field.php | 6 + administrator/models/forms/field.xml | 2 +- administrator/models/rules/cluster.php | 23 +- site/filterFields.php | 25 +- site/helpers/tjfields.php | 436 ++++++++++++++++++++- site_language/en-GB/en-GB.com_tjfields.ini | 5 +- 6 files changed, 486 insertions(+), 11 deletions(-) diff --git a/administrator/models/field.php b/administrator/models/field.php index 83d50f54..8d202757 100755 --- a/administrator/models/field.php +++ b/administrator/models/field.php @@ -305,6 +305,12 @@ public function save($data) $data_unique_name = $client . '_' . $data['client_type'] . '_' . $data['type'] . 'createdby'; } + // To store itemcategory type fields in core UCM hence rename the field name + if ($data['type'] == 'itemcategory') + { + $data_unique_name = $client . '_' . $data['client_type'] . '_' . $data['type'] . 'itemcategory'; + } + $data['name'] = $data_unique_name; } diff --git a/administrator/models/forms/field.xml b/administrator/models/forms/field.xml index 6ed26ab6..bf0de463 100755 --- a/administrator/models/forms/field.xml +++ b/administrator/models/forms/field.xml @@ -19,7 +19,7 @@ - + diff --git a/administrator/models/rules/cluster.php b/administrator/models/rules/cluster.php index afd984af..f3ff2d5a 100644 --- a/administrator/models/rules/cluster.php +++ b/administrator/models/rules/cluster.php @@ -34,20 +34,35 @@ class JFormRuleCluster extends JFormRule */ public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) { + $required = ($element['required'] instanceof SimpleXMLElement) ? $element['required']->__toString() : 'false'; + + if ($required == 'true') + { + if ($value == "" || empty($value)) + { + return false; + } + } + // Validate if a user has entered valid cluster id $user = JFactory::getUser(); JLoader::import("/components/com_cluster/includes/cluster", JPATH_ADMINISTRATOR); $clusterUserModel = ClusterFactory::model('ClusterUser', array('ignore_request' => true)); $clusters = $clusterUserModel->getUsersClusters($user->id); - foreach ($clusters as $cluster) + if ($value != "") { - if ($value == $cluster->id) + foreach ($clusters as $cluster) { - return true; + if ($value == $cluster->id) + { + return true; + } } + + return false; } - return false; + return true; } } diff --git a/site/filterFields.php b/site/filterFields.php index 3121a651..83075069 100755 --- a/site/filterFields.php +++ b/site/filterFields.php @@ -421,13 +421,30 @@ public function getDataExtra($data, $id = null) */ public function saveExtraFields($data) { - $tjFieldsHelper = new TjfieldsHelper; + if (empty($data['client'])) + { + $this->setError(JText::_('COM_TJFIELDS_FORM_SAVE_FAILED_CLIENT_REQUIRED')); - $data['user_id'] = JFactory::getUser()->id; + return false; + } - $result = $tjFieldsHelper->saveFieldsValue($data); + if (empty($data['content_id'])) + { + $this->setError(JText::_('COM_TJFIELDS_FORM_SAVE_FAILED_CLIENT_REQUIRED')); - return $result; + return false; + } + + if (empty($data['fieldsvalue'])) + { + $this->setError(JText::_('COM_TJFIELDS_FORM_SAVE_FAILED_CLIENT_REQUIRED')); + + return false; + } + + $tjFieldsHelper = new TjfieldsHelper; + + return $tjFieldsHelper->saveFieldsValue($data); } /** diff --git a/site/helpers/tjfields.php b/site/helpers/tjfields.php index 5c9b7409..a37936f9 100644 --- a/site/helpers/tjfields.php +++ b/site/helpers/tjfields.php @@ -9,6 +9,7 @@ defined('_JEXEC') or die; JLoader::import("/techjoomla/media/storage/local", JPATH_LIBRARIES); +use Joomla\Registry\Registry; /** * Helper class for tjfields @@ -153,6 +154,439 @@ public function getFieldData($fname = '', $fid = '') return $field_data; } + /** + * Function to store data in fields_value table + * + * @param ARRAY $data Data to be stored + * + * @return boolean + */ + public function saveFieldsValue($data) + { + if (empty($data['content_id']) || empty($data['client']) || empty($data['fieldsvalue'])) + { + return false; + } + + static $tjUcmParentClient; + static $tjUcmParentContentId; + static $tjUcmSubFormContentId = array('childContentIds' => array()); + + if (empty($tjUcmParentClient)) + { + $tjUcmParentClient = $data['client']; + } + + if (empty($tjUcmParentContentId)) + { + $tjUcmParentContentId = $data['content_id']; + } + + // Get user object + $user = JFactory::getUser(); + + // Get all the fields of the specified client + JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); + $tjFieldsFieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); + $tjFieldsFieldsModel->setState('filter.client', $data['client']); + $tjFieldsFieldsModel->setState('filter.state', 1); + $fields = $tjFieldsFieldsModel->getItems(); + + // Get previously stored details in the record + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('*'); + $query->from($db->quoteName('#__tjfields_fields_value')); + $query->where($db->quoteName('content_id') . ' = ' . (INT) $data['content_id']); + $query->where($db->quoteName('client') . ' = ' . $db->quote($data['client'])); + $db->setQuery($query); + $storedValues = $db->loadAssocList(); + + foreach ($data['fieldsvalue'] as $fieldName => $fieldValue) + { + $fieldKey = array_search($fieldName, array_column($fields, 'name')); + $field = $fields[$fieldKey]; + + $fieldStoredValuesKeys = array_keys(array_column($storedValues, 'field_id'), $field->id); + $fieldStoredValues = array(); + + foreach ($fieldStoredValuesKeys as $fieldStoredValuesKey) + { + $fieldStoredValues[] = $storedValues[$fieldStoredValuesKey]; + } + + // Check if user is authorised to save/edit the field value + if (empty($storedValues)) + { + if ($user->authorise('core.field.addfieldvalue', 'com_tjfields.group.' . $field->group_id)) + { + $authorised = $user->authorise('core.field.addfieldvalue', 'com_tjfields.field.' . $field->id); + } + } + else + { + if ($user->authorise('core.field.editfieldvalue', 'com_tjfields.group.' . $field->group_id)) + { + $authorised = $user->authorise('core.field.editfieldvalue', 'com_tjfields.field.' . $field->id); + } + else + { + if ($user->authorise('core.field.editownfieldvalue', 'com_tjfields.group.' . $field->group_id)) + { + if ($user->authorise('core.field.editownfieldvalue', 'com_tjfields.field.' . $field->id) && ($data['created_by'] == $user->id)) + { + $authorised = true; + } + } + } + } + + // If not authorised then return false + if (empty($authorised)) + { + continue; + } + + if ($field->type == 'file' || $field->type == 'image') + { + $this->saveMediaFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); + } + elseif ($field->type == 'subform') + { + $fieldValue = json_encode($fieldValue); + $this->saveSingleValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); + } + elseif ($field->type == 'ucmsubform' && is_array($fieldValue)) + { + if (empty($fieldValue)) + { + continue; + } + + if (!defined('TJUCM_PARENT_CLIENT')) + { + define("TJUCM_PARENT_CLIENT", $data['client']); + } + + if (!defined('TJUCM_PARENT_CONTENT_ID')) + { + define("TJUCM_PARENT_CONTENT_ID", $data['content_id']); + } + + $ucmSubformClientTmp = explode('_', str_replace("com_tjucm_", '', array_key_first($fieldValue[array_key_first($fieldValue)]))); + array_pop($ucmSubformClientTmp); + $ucmSubformClient = 'com_tjucm.' . implode('_', $ucmSubformClientTmp); + + $this->saveSingleValuedFieldData($ucmSubformClient, TJUCM_PARENT_CLIENT, TJUCM_PARENT_CONTENT_ID, $field->id, $fieldStoredValues); + + foreach ($fieldValue as $key => $ucmSubformValue) + { + if (!empty($ucmSubformValue)) + { + $ucmSubformContentIdFieldName = str_replace('.', '_', $ucmSubformClient . "_contentid"); + $ucmSubformContentIdFieldElementId = 'jform_' . $field->name . '__' . $key . '__' . $ucmSubformContentIdFieldName; + $ucmSubFormContentId = (INT) (isset($ucmSubformValue[$ucmSubformContentIdFieldName])) ? $ucmSubformValue[$ucmSubformContentIdFieldName] : 0; + + if (empty($ucmSubFormContentId)) + { + $tjUcmSubFormItemData = array('id' => '', 'parent_id' => $data['content_id'], 'client' => $ucmSubformClient); + + JLoader::import('component.com_tjucm.models.itemform', JPATH_SITE); + $tjUcmItemFormModel = JModelLegacy::getInstance('ItemForm', 'TjucmModel'); + $tjUcmItemFormModel->save($tjUcmSubFormItemData); + $ucmSubFormContentId = $tjUcmItemFormModel->getState($tjUcmItemFormModel->getName() . '.id'); + } + + $tjUcmSubFormContentId['childContentIds'][$ucmSubformContentIdFieldElementId] = (INT) $ucmSubFormContentId; + $ucmSubFormData = array(); + $ucmSubFormData['content_id'] = $ucmSubFormContentId; + $ucmSubFormData['client'] = $ucmSubformClient; + $ucmSubFormData['fieldsvalue'] = $ucmSubformValue; + $ucmSubFormData['created_by'] = JFactory::getUser()->id; + $this->saveFieldsValue($ucmSubFormData); + } + } + } + elseif (is_array($fieldValue)) + { + $fieldValue = explode(",", $fieldValue[0]); + + $this->saveMultiValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); + } + else + { + $this->saveSingleValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); + } + } + + if (!empty($tjUcmSubFormContentId['childContentIds'])) + { + return $tjUcmSubFormContentId; + } + + return true; + } + + /** + * Function to store data of single valued field in fields_value table + * + * @param STRING $fieldValue Data to be stored + * @param STRING $client Client to which the data belongs + * @param INT $contentId Record Id to which the data belongs + * @param INT $fieldId Field Id to which the data belongs + * @param ARRAY $fieldStoredValues Previously stored value if any + * + * @return boolean + */ + private function saveSingleValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) + { + if (empty($contentId) || empty($fieldId) || empty($client)) + { + return false; + } + + JLoader::import('components.com_tjfields.tables.fieldsvalue', JPATH_ADMINISTRATOR); + $fieldsValueTable = JTable::getInstance('FieldsValue', 'TjfieldsTable', array('dbo', JFactory::getDbo())); + + // Set currently logged in users id as user_id + $fieldsValueTable->user_id = JFactory::getUser()->id; + + // If field value already exists then update the value else insert the field value + if (isset($fieldStoredValues[0]) || !empty($fieldStoredValues[0])) + { + if ($fieldsValueTable->bind($fieldStoredValues[0])) + { + // If new value for field is not blank then update it else delete it + if ($fieldValue != '') + { + $fieldsValueTable->value = $fieldValue; + + if ($fieldsValueTable->store()) + { + return true; + } + } + else + { + if ($fieldsValueTable->delete($fieldStoredValues[0]['id'])) + { + return true; + } + } + } + } + else + { + $fieldsValueTable->field_id = $fieldId; + $fieldsValueTable->content_id = $contentId; + $fieldsValueTable->value = $fieldValue; + $fieldsValueTable->client = $client; + + if ($fieldsValueTable->store()) + { + return true; + } + } + + return false; + } + + /** + * Function to store data of multi valued field in fields_value table + * + * @param ARRAY $fieldValue Data to be stored + * @param STRING $client Client to which the data belongs + * @param INT $contentId Record Id to which the data belongs + * @param INT $fieldId Field Id to which the data belongs + * @param ARRAY $fieldStoredValues Previously stored value if any + * + * @return boolean + */ + private function saveMultiValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) + { + if (empty($contentId) || empty($fieldId) || empty($client)) + { + return false; + } + + $db = JFactory::getDbo(); + $previouslyStoredValues = array(); + + if (!empty($fieldStoredValues)) + { + // Get deleted options + $previouslyStoredValues = array_column($fieldStoredValues, 'value'); + $valuesToDelete = array(); + + foreach ($previouslyStoredValues as $previouslyStoredValue) + { + // Get the unselected options + if (!in_array($previouslyStoredValue, $fieldValue)) + { + $valuesToDelete[] = $previouslyStoredValue; + } + } + + // Delete the unselected options + if (!empty($valuesToDelete)) + { + $query = $db->getQuery(true); + $conditions = array( + $db->quoteName('value') . ' IN (' . implode(',', $db->quote($valuesToDelete)) . ')', + $db->quoteName('client') . ' = ' . $db->quote($client), + $db->quoteName('field_id') . ' = ' . $fieldId, + $db->quoteName('content_id') . ' = ' . $contentId + ); + + $query->delete($db->quoteName('#__tjfields_fields_value')); + $query->where($conditions); + $db->setQuery($query); + $db->execute(); + } + } + + // Insert record for newly selected options + if (!empty($fieldValue)) + { + foreach ($fieldValue as $value) + { + if (!in_array($value, $previouslyStoredValues)) + { + $status = $this->saveSingleValuedFieldData($value, $client, $contentId, $fieldId); + + if ($status === false) + { + return false; + } + } + } + } + + return true; + } + + /** + * Function to store data of media field in fields_value table + * + * @param ARRAY $fieldValue Data to be stored + * @param STRING $client Client to which the data belongs + * @param INT $contentId Record Id to which the data belongs + * @param INT $fieldId Field Id to which the data belongs + * @param ARRAY $fieldStoredValues Previously stored value if any + * + * @return boolean + */ + private function saveMediaFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) + { + if (empty($contentId) || empty($fieldId) || empty($client)) + { + return false; + } + + if (empty($fieldValue['name']) && empty($fieldValue['tmp_name']) && empty($fieldValue['size'])) + { + return false; + } + + JLoader::import('components.com_tjfields.tables.fieldsvalue', JPATH_ADMINISTRATOR); + $fieldsValueTable = JTable::getInstance('FieldsValue', 'TjfieldsTable', array('dbo', JFactory::getDbo())); + + JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); + $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', JFactory::getDbo())); + $fieldTable->load($fieldId); + $fieldParams = new Registry($fieldTable->params); + + // Get media library object + $mediaLibObj = TJMediaStorageLocal::getInstance(); + + // Configs for Media library + $config = array(); + + // Configure MIME type for media library + $mimeTypes = $fieldParams->get('accept', ''); + + if (!empty($mimeTypes)) + { + $mimeTypes = explode(',', $mimeTypes); + + $validMineType = array(); + + foreach ($mimeTypes as $mimeType) + { + $validMineType[] = $mediaLibObj->getMime(strtolower(str_ireplace('.', '', $mimeType))); + } + + $config['type'] = $validMineType; + } + + // Configure allowed extensions for media library + if (!empty($mimeTypes)) + { + $mimeTypes = explode(',', $mimeTypes); + + foreach ($mimeTypes as $j => $allowedType) + { + $mimeTypes[$j] = trim(str_replace('.', '', $allowedType)); + } + + $config['allowedExtension'] = $mimeTypes; + } + + // Configure media path for the media library + $uploadPath = $fieldParams->get('uploadpath', ''); + $mediaPath = ($uploadPath != '') ? $uploadPath : JPATH_SITE . '/' . $fieldTable->type . 's/tjmedia/' . str_replace(".", "/", $client . "/"); + $config['uploadPath'] = $mediaPath; + + // Configure size for the media library + $config['size'] = $fieldParams->get('size'); + + // Configure whether to store the media related data in the media table + $config['saveData'] = '0'; + + // Configure if user is authorised to add the media + $config['auth'] = true; + + $mediaLibObj = TJMediaStorageLocal::getInstance($config); + $returnData = $mediaLibObj->upload(array($fieldValue)); + $errors = $mediaLibObj->getErrors(); + + if (!empty($errors)) + { + foreach ($errors as $error) + { + JFactory::getApplication()->enqueueMessage($error, 'error'); + } + + return false; + } + + // Add htaccess file in the folder where the file is uploaded so that its not accessible through URL + if ($fieldTable->type == 'file') + { + $htaccessFileContent = ' + Order Allow,Deny + Deny from All + '; + $htaccess = '.htaccess'; + $htaccessFile = $mediaPath . '/' . $htaccess; + + // If the destination directory doesn't exist we need to create it + jimport('joomla.filesystem.file'); + + if (!JFile::exists($htaccessFile)) + { + jimport('joomla.filesystem.folder'); + JFolder::create(dirname($htaccessFile)); + JFile::write($htaccessFile, $htaccessFileContent); + } + } + + // Add/Update value of the file field in fields_value table + $fieldValue = $returnData[0]['source']; + + return $this->saveSingleValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues); + } + /** * Save fields. * @@ -160,7 +594,7 @@ public function getFieldData($fname = '', $fid = '') * * @return bool Returns true if successful, and false otherwise. */ - public function saveFieldsValue($data) + public function saveFieldsValueTOBEDELETED($data) { if (empty($data)) { diff --git a/site_language/en-GB/en-GB.com_tjfields.ini b/site_language/en-GB/en-GB.com_tjfields.ini index 52ea3b15..93cbd8fa 100644 --- a/site_language/en-GB/en-GB.com_tjfields.ini +++ b/site_language/en-GB/en-GB.com_tjfields.ini @@ -1,4 +1,4 @@ -COM_TJUCM_MSG_ON_SAVED_FORM="Data saved successfully." +COM_TJFIELDS_MSG_ON_SAVED_FORM="Data saved successfully." COM_TJFIELDS="tjfields" COM_TJFIELDS_ITEM_SAVED_SUCCESSFULLY="Item saved successfully" COM_TJFIELDS_ITEM_DELETED_SUCCESSFULLY="Item deleted successfully" @@ -22,6 +22,9 @@ COM_TJFIELDS_FILE_ERROR_INVALID_TYPE="Invalid file type" COM_TJFIELDS_FILE_ERROR_MAX_SIZE="File size should be less than or equal to allowed size" COM_TJFIELDS_FILE_DELETE="Delete" COM_TJFIELDS_FILE_ERROR_MOVE_FILE="Error in moving file" +COM_TJFIELDS_FORM_SAVE_FAILED_CLIENT_REQUIRED="Unable to process the request as client is not provided" +COM_TJFIELDS_FORM_SAVE_FAILED_RECORD_ID_REQUIRED="Unable to process the request as record id is not provided" +COM_TJFIELDS_FORM_SAVE_FAILED_FIELD_DATA_REQUIRED="Unable to process the request as field data is not provided" ; Delete file type COM_TJFIELDS_FILE_DELETE_SUCCESS="File deleted successfully."