From a235763c386885d04986d9856394ad76b9231c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Thu, 17 Oct 2019 18:11:16 +0530 Subject: [PATCH] Bug #205 fix: For list type of field, value is shown on list and details view instead of label --- administrator/models/field.php | 23 +- administrator/models/fields/related.php | 2 +- administrator/models/fields/sql.php | 320 ++++++++++++++++++ administrator/models/forms/field.xml | 51 +-- site/helpers/tjfields.php | 62 ++-- site/layouts/fields/calendar.php | 4 - site/layouts/fields/checkbox.php | 4 - site/layouts/fields/cluster.php | 6 +- site/layouts/fields/field.php | 6 +- site/layouts/fields/file.php | 4 - site/layouts/fields/image.php | 6 +- site/layouts/fields/itemcategory.php | 4 - site/layouts/fields/link.php | 6 +- site/layouts/fields/list.php | 10 +- .../fields/{video.php => ownership.php} | 18 +- site/layouts/fields/sql.php | 54 ++- site/layouts/fields/subform.php | 84 +++++ 17 files changed, 494 insertions(+), 170 deletions(-) create mode 100644 administrator/models/fields/sql.php rename site/layouts/fields/{video.php => ownership.php} (52%) create mode 100644 site/layouts/fields/subform.php diff --git a/administrator/models/field.php b/administrator/models/field.php index 8d202757..28f0c2ab 100755 --- a/administrator/models/field.php +++ b/administrator/models/field.php @@ -84,7 +84,7 @@ public function getForm($data = array(), $loadData = true) } } - if ($form->getValue('type') == 'ucmsubform') + if ($form->getValue('type') == 'ucmsubform' || $form->getValue('type') == 'subform') { $form->setValue('showonlist', null, 0); $form->removeField('showonlist'); @@ -796,4 +796,25 @@ public function delete(&$pks) return true; } + + /** + * Method to get JForm for subform field. + * + * @param STRING $name name of the form + * @param STRING $formSource form source path + * @param OBJECT $loadData data to be loaded + * + * @return mixed JForm object if successful, false if an error occurs. + * + * @since 1.4.3 + */ + public function getSubFormFieldForm($name, $formSource, $loadData = array()) + { + if (empty($name) || empty($formSource) || !JFile::exists($formSource)) + { + return false; + } + + return $this->loadForm($name, $formSource, array('control' => 'jform','load_data' => $loadData)); + } } diff --git a/administrator/models/fields/related.php b/administrator/models/fields/related.php index 46d13bc1..47e71d3c 100644 --- a/administrator/models/fields/related.php +++ b/administrator/models/fields/related.php @@ -39,7 +39,7 @@ class JFormFieldRelated extends JFormFieldList * * @since 3.7.0 */ - protected function getOptions() + public function getOptions() { // Load TJ-Fields language file $lang = Factory::getLanguage()->load('com_tjfields', JPATH_ADMINISTRATOR); diff --git a/administrator/models/fields/sql.php b/administrator/models/fields/sql.php new file mode 100644 index 00000000..0f0a413c --- /dev/null +++ b/administrator/models/fields/sql.php @@ -0,0 +1,320 @@ +$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.2 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'keyField': + case 'valueField': + case 'translate': + case 'query': + $this->$name = (string) $value; + break; + + default: + parent::__set($name, $value); + } + } + + /** + * Method to attach a JForm object to the field. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.2 + */ + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + if ($return) + { + // Check if its using the old way + $this->query = (string) $this->element['query']; + + if (empty($this->query)) + { + // Get the query from the form + $query = array(); + $defaults = array(); + + $sql_select = (string) $this->element['sql_select']; + $sql_from = (string) $this->element['sql_from']; + + if ($sql_select && $sql_from) + { + $query['select'] = $sql_select; + $query['from'] = $sql_from; + $query['join'] = (string) $this->element['sql_join']; + $query['where'] = (string) $this->element['sql_where']; + $query['group'] = (string) $this->element['sql_group']; + $query['order'] = (string) $this->element['sql_order']; + + // Get the filters + $filters = isset($this->element['sql_filter']) ? explode(',', $this->element['sql_filter']) : ''; + + // Get the default value for query if empty + if (is_array($filters)) + { + foreach ($filters as $filter) + { + $name = "sql_default_{$filter}"; + $attrib = (string) $this->element[$name]; + + if (!empty($attrib)) + { + $defaults[$filter] = $attrib; + } + } + } + + // Process the query + $this->query = $this->processQuery($query, $filters, $defaults); + } + } + + $this->keyField = (string) $this->element['key_field'] ?: 'value'; + $this->valueField = (string) $this->element['value_field'] ?: (string) $this->element['name']; + $this->translate = (string) $this->element['translate'] ?: false; + $this->header = (string) $this->element['header'] ?: false; + } + + return $return; + } + + /** + * Method to process the query from form. + * + * @param array $conditions The conditions from the form. + * @param string $filters The columns to filter. + * @param array $defaults The defaults value to set if condition is empty. + * + * @return JDatabaseQuery The query object. + * + * @since 3.5 + */ + protected function processQuery($conditions, $filters, $defaults) + { + // Get the database object. + $db = JFactory::getDbo(); + + // Get the query object + $query = $db->getQuery(true); + + // Select fields + $query->select($conditions['select']); + + // From selected table + $query->from($conditions['from']); + + // Join over the groups + if (!empty($conditions['join'])) + { + $query->join('LEFT', $conditions['join']); + } + + // Where condition + if (!empty($conditions['where'])) + { + $query->where($conditions['where']); + } + + // Group by + if (!empty($conditions['group'])) + { + $query->group($conditions['group']); + } + + // Process the filters + if (is_array($filters)) + { + $html_filters = JFactory::getApplication()->getUserStateFromRequest($this->context . '.filter', 'filter', array(), 'array'); + + foreach ($filters as $k => $value) + { + if (!empty($html_filters[$value])) + { + $escape = $db->quote($db->escape($html_filters[$value]), false); + + $query->where("{$value} = {$escape}"); + } + elseif (!empty($defaults[$value])) + { + $escape = $db->quote($db->escape($defaults[$value]), false); + + $query->where("{$value} = {$escape}"); + } + } + } + + // Add order to query + if (!empty($conditions['order'])) + { + $query->order($conditions['order']); + } + + return $query; + } + + /** + * Method to get the custom field options. + * Use the query attribute to supply a query to generate the list. + * + * @return array The field option objects. + * + * @since 1.7.0 + */ + public function getOptions() + { + $options = array(); + + // Initialize some field attributes. + $key = $this->keyField; + $value = $this->valueField; + $header = $this->header; + + if ($this->query) + { + // Get the database object. + $db = JFactory::getDbo(); + + // Set the query and get the result list. + $db->setQuery($this->query); + + try + { + $items = $db->loadObjectlist(); + } + catch (JDatabaseExceptionExecuting $e) + { + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); + } + } + + // Add header. + if (!empty($header)) + { + $header_title = JText::_($header); + $options[] = JHtml::_('select.option', '', $header_title); + } + + // Build the field options. + if (!empty($items)) + { + foreach ($items as $item) + { + if ($this->translate == true) + { + $options[] = JHtml::_('select.option', $item->$key, JText::_($item->$value)); + } + else + { + $options[] = JHtml::_('select.option', $item->$key, $item->$value); + } + } + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/administrator/models/forms/field.xml b/administrator/models/forms/field.xml index bf0de463..a6e6d918 100755 --- a/administrator/models/forms/field.xml +++ b/administrator/models/forms/field.xml @@ -2,88 +2,45 @@
- - - - - - - - - - - - - - - - - - - - - + - - - + + +
diff --git a/site/helpers/tjfields.php b/site/helpers/tjfields.php index 35a89b3a..453294a8 100644 --- a/site/helpers/tjfields.php +++ b/site/helpers/tjfields.php @@ -249,12 +249,12 @@ public function saveFieldsValue($data) if ($field->type == 'file' || $field->type == 'image') { - $this->saveMediaFieldData($fieldValue, $field->client, $data['content_id'], $field, $fieldStoredValues); + $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, $fieldStoredValues); + $this->saveSingleValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); } elseif ($field->type == 'ucmsubform' && is_array($fieldValue)) { @@ -277,7 +277,7 @@ public function saveFieldsValue($data) array_pop($ucmSubformClientTmp); $ucmSubformClient = 'com_tjucm.' . implode('_', $ucmSubformClientTmp); - $this->saveSingleValuedFieldData($ucmSubformClient, TJUCM_PARENT_CLIENT, TJUCM_PARENT_CONTENT_ID, $field, $fieldStoredValues); + $this->saveSingleValuedFieldData($ucmSubformClient, TJUCM_PARENT_CLIENT, TJUCM_PARENT_CONTENT_ID, $field->id, $fieldStoredValues); foreach ($fieldValue as $key => $ucmSubformValue) { @@ -309,16 +309,13 @@ public function saveFieldsValue($data) } elseif (is_array($fieldValue)) { - if (strpos($fieldValue[0], ',')) - { - $fieldValue = explode(",", $fieldValue[0]); - } + $fieldValue = explode(",", $fieldValue[0]); - $this->saveMultiValuedFieldData($fieldValue, $field->client, $data['content_id'], $field, $fieldStoredValues); + $this->saveMultiValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); } else { - $this->saveSingleValuedFieldData($fieldValue, $field->client, $data['content_id'], $field, $fieldStoredValues); + $this->saveSingleValuedFieldData($fieldValue, $field->client, $data['content_id'], $field->id, $fieldStoredValues); } } @@ -336,14 +333,14 @@ public function saveFieldsValue($data) * @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 OBJECT $field Field table object 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, $field, $fieldStoredValues = array()) + private function saveSingleValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) { - if (empty($contentId) || empty($field->id) || empty($client)) + if (empty($contentId) || empty($fieldId) || empty($client)) { return false; } @@ -368,6 +365,11 @@ private function saveSingleValuedFieldData($fieldValue, $client, $contentId, $fi if ($fieldValue != '') { $fieldsValueTable->value = $fieldValue; + + if ($fieldsValueTable->store()) + { + return true; + } } else { @@ -380,26 +382,18 @@ private function saveSingleValuedFieldData($fieldValue, $client, $contentId, $fi } else { - $fieldsValueTable->field_id = $field->id; + $fieldsValueTable->field_id = $fieldId; $fieldsValueTable->content_id = $contentId; $fieldsValueTable->value = $fieldValue; $fieldsValueTable->client = $client; - } - // For single select, multi select and radio field type we need to save option_id as well in fields value table - if (in_array($field->type, array('radio', 'tjlist', 'single_select', 'multi_select'))) - { - JLoader::import('components.com_tjfields.tables.option', JPATH_ADMINISTRATOR); - $fieldOptionTable = JTable::getInstance('Option', 'TjfieldsTable', array('dbo', JFactory::getDbo())); - $fieldOptionTable->load(array('field_id' => $field->id, 'value' => $fieldValue)); - - if ($fieldOptionTable->id) + if ($fieldsValueTable->store()) { - $fieldsValueTable->option_id = $fieldOptionTable->id; + return true; } } - return $fieldsValueTable->store(); + return false; } /** @@ -408,14 +402,14 @@ private function saveSingleValuedFieldData($fieldValue, $client, $contentId, $fi * @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 OBJECT $field Field table object 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, $field, $fieldStoredValues = array()) + private function saveMultiValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) { - if (empty($contentId) || empty($field->id) || empty($client)) + if (empty($contentId) || empty($fieldId) || empty($client)) { return false; } @@ -445,7 +439,7 @@ private function saveMultiValuedFieldData($fieldValue, $client, $contentId, $fie $conditions = array( $db->quoteName('value') . ' IN (' . implode(',', $db->quote($valuesToDelete)) . ')', $db->quoteName('client') . ' = ' . $db->quote($client), - $db->quoteName('field_id') . ' = ' . $field->id, + $db->quoteName('field_id') . ' = ' . $fieldId, $db->quoteName('content_id') . ' = ' . $contentId ); @@ -463,7 +457,7 @@ private function saveMultiValuedFieldData($fieldValue, $client, $contentId, $fie { if (!in_array($value, $previouslyStoredValues)) { - $status = $this->saveSingleValuedFieldData($value, $client, $contentId, $field); + $status = $this->saveSingleValuedFieldData($value, $client, $contentId, $fieldId); if ($status === false) { @@ -482,14 +476,14 @@ private function saveMultiValuedFieldData($fieldValue, $client, $contentId, $fie * @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 OBJECT $field Field table object 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, $field, $fieldStoredValues = array()) + private function saveMediaFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues = array()) { - if (empty($contentId) || empty($field->id) || empty($client)) + if (empty($contentId) || empty($fieldId) || empty($client)) { return false; } @@ -504,7 +498,7 @@ private function saveMediaFieldData($fieldValue, $client, $contentId, $field, $f JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', JFactory::getDbo())); - $fieldTable->load($field->id); + $fieldTable->load($fieldId); $fieldParams = new Registry($fieldTable->params); // Get media library object @@ -595,7 +589,7 @@ private function saveMediaFieldData($fieldValue, $client, $contentId, $field, $f // Add/Update value of the file field in fields_value table $fieldValue = $returnData[0]['source']; - return $this->saveSingleValuedFieldData($fieldValue, $client, $contentId, $field, $fieldStoredValues); + return $this->saveSingleValuedFieldData($fieldValue, $client, $contentId, $fieldId, $fieldStoredValues); } /** diff --git a/site/layouts/fields/calendar.php b/site/layouts/fields/calendar.php index 0fb86097..af75a925 100644 --- a/site/layouts/fields/calendar.php +++ b/site/layouts/fields/calendar.php @@ -23,7 +23,3 @@ { echo $date->format($format); } -else -{ - echo "-"; -} diff --git a/site/layouts/fields/checkbox.php b/site/layouts/fields/checkbox.php index 0795eff4..27d867ff 100644 --- a/site/layouts/fields/checkbox.php +++ b/site/layouts/fields/checkbox.php @@ -22,8 +22,4 @@ $checked = ($field->value == 1) ? ' checked="checked"' : '';?> /> true)); $cluster = $clusterModel->getItem($field->value); echo $cluster->name; -} -else -{ - echo "-"; -} +} \ No newline at end of file diff --git a/site/layouts/fields/field.php b/site/layouts/fields/field.php index dcb3d8b2..a469a570 100644 --- a/site/layouts/fields/field.php +++ b/site/layouts/fields/field.php @@ -32,8 +32,4 @@ { echo htmlspecialchars($field->value, ENT_COMPAT, 'UTF-8'); } -} -else -{ - echo "-"; -} +} \ No newline at end of file diff --git a/site/layouts/fields/file.php b/site/layouts/fields/file.php index 48c814a5..896857e7 100644 --- a/site/layouts/fields/file.php +++ b/site/layouts/fields/file.php @@ -39,8 +39,4 @@ $tjFieldHelper = new TjfieldsHelper; $mediaLink = $tjFieldHelper->getMediaUrl($field->value, $extraParamArray); echo "" . JText::_("COM_TJFIELDS_FILE_DOWNLOAD") . ""; -} -else -{ - echo "-"; } \ No newline at end of file diff --git a/site/layouts/fields/image.php b/site/layouts/fields/image.php index ac39b5ba..369f7c1f 100644 --- a/site/layouts/fields/image.php +++ b/site/layouts/fields/image.php @@ -56,8 +56,4 @@ load($categoryId); echo htmlspecialchars($categoryTable->title, ENT_COMPAT, 'UTF-8'); -} -else -{ - echo "-"; } \ No newline at end of file diff --git a/site/layouts/fields/link.php b/site/layouts/fields/link.php index 6e9a4854..1dc3cb20 100644 --- a/site/layouts/fields/link.php +++ b/site/layouts/fields/link.php @@ -23,8 +23,4 @@ // This is working for normal form video field $languageConstant = "COM_TJFIELDS_VIEW_FIELD_" . strtoupper($field->type); echo "" . JText::_($languageConstant) . ""; -} -else -{ - echo "-"; -} +} \ No newline at end of file diff --git a/site/layouts/fields/list.php b/site/layouts/fields/list.php index e8c7b6b6..910ad1a1 100644 --- a/site/layouts/fields/list.php +++ b/site/layouts/fields/list.php @@ -40,7 +40,7 @@ if (isset($options[$field->value])) { $options[$field->value] = htmlspecialchars($options[$field->value], ENT_COMPAT, 'UTF-8'); - echo ucfirst($options[$field->value]); + echo JText::_(ucfirst($options[$field->value])); } } else @@ -51,13 +51,9 @@ if (isset($options[$value])) { $options[$value] = htmlspecialchars($options[$value], ENT_COMPAT, 'UTF-8'); - echo ucfirst($options[$value]); + echo JText::_(ucfirst($options[$value])); echo "
"; } } } -} -else -{ - echo "-"; -} +} \ No newline at end of file diff --git a/site/layouts/fields/video.php b/site/layouts/fields/ownership.php similarity index 52% rename from site/layouts/fields/video.php rename to site/layouts/fields/ownership.php index 658d7f3c..531f39c5 100644 --- a/site/layouts/fields/video.php +++ b/site/layouts/fields/ownership.php @@ -9,9 +9,7 @@ // No direct access defined('_JEXEC') or die('Restricted access'); -use Joomla\CMS\Language\Text; - -if (!key_exists('field', $displayData) || !key_exists('fieldXml', $displayData)) +if (!key_exists('field', $displayData)) { return; } @@ -20,10 +18,10 @@ if ($field->value) { - // This is working for normal form video field. Needs improvement for video field in subform - echo "" . JText::_("COM_TJUCM_VIDEO_FIELD_VALUE") . ""; -} -else -{ - echo "-"; -} + $owner = JFactory::getUser($field->value); + + if ($owner->id) + { + echo $owner->username; + } +} \ No newline at end of file diff --git a/site/layouts/fields/sql.php b/site/layouts/fields/sql.php index f12538dc..e967fcac 100644 --- a/site/layouts/fields/sql.php +++ b/site/layouts/fields/sql.php @@ -23,46 +23,32 @@ return; } -$db = JFactory::getDbo(); -$value = (array) $value; -$condition = ''; +$options = $field->getOptions(); +$fieldOptions = array(); -foreach ($value as $v) +foreach ($options as $option) { - if (!$v) - { - continue; - } - - $condition .= ', ' . $db->q($v); + $option = (object) $option; + $fieldOptions[$option->value] = JText::_(ucfirst(htmlspecialchars($option->text, ENT_COMPAT, 'UTF-8'))); } -$query = $field->getAttribute('query'); -$keyColumn = $field->getAttribute('key_field'); -$valueColumn = $field->getAttribute('value_field'); - -// Run the query with a having condition because it supports aliases -$db->setQuery($query . ' having ' . $keyColumn . ' in (' . trim($condition, ',') . ')'); - -try -{ - $items = $db->loadObjectlist(); -} -catch (Exception $e) +if (!is_array($field->value)) { - // If the query failed, we fetch all elements - $db->setQuery($query); - $items = $db->loadObjectlist(); + // If single select + if (isset($fieldOptions[$field->value])) + { + echo $fieldOptions[$field->value]; + } } - -$texts = array(); - -foreach ($items as $item) +else { - if (in_array($item->$keyColumn, $value)) + // If multi select + foreach ($field->value as $value) { - $texts[] = $item->$valueColumn; + if (isset($fieldOptions[$value])) + { + echo $fieldOptions[$value]; + echo "
"; + } } -} - -echo htmlentities(implode(', ', $texts)); +} \ No newline at end of file diff --git a/site/layouts/fields/subform.php b/site/layouts/fields/subform.php new file mode 100644 index 00000000..a8d57a03 --- /dev/null +++ b/site/layouts/fields/subform.php @@ -0,0 +1,84 @@ + + * @copyright Copyright (c) 2009-2019 TechJoomla. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access +defined('_JEXEC') or die('Restricted access'); + +if (!key_exists('field', $displayData) || !key_exists('fieldXml', $displayData)) +{ + return; +} + +JLoader::import('components.com_tjfields.models.field', JPATH_ADMINISTRATOR); + +$xmlField = $displayData['fieldXml']; +$field = $displayData['field']; +$formSource = $field->formsource; + +if ($field->value) +{ + foreach ($field->value as $name => $subformData) + { + $subformData = (array) $subformData; + $tjFieldsFieldModel = JModelLegacy::getInstance('Field', 'TjfieldsModel'); + $form = $tjFieldsFieldModel->getSubFormFieldForm($name, $formSource); + ?> +
+ getFieldsets() as $fieldSet) + { + $fieldSet = $form->getFieldset($fieldSet->name); + + foreach ($fieldSet as $field) + { + ?> +
+ getAttribute('label')); + ?> +
+
+ type == 'List' || $field->type == 'Radio') + { + $fieldXml = $form->getFieldXml($field->getAttribute('name')); + $field->value = $subformData[$field->getAttribute('name')]; + + $layout = new JLayoutFile('list', JPATH_ROOT . '/components/com_tjfields/layouts/fields'); + echo $layout->render(array('fieldXml' => $fieldXml, 'field' => $field)); + } + elseif ($field->type == 'Checkbox') + { + if ($subformData[$field->getAttribute('name')]) + { + ?> + + + + getAttribute('name')]; + } + ?> +
+ +
+
+